Partage
  • Partager sur Facebook
  • Partager sur Twitter

Architecture php

Sujet résolu
    5 avril 2020 à 21:07:06

    Bonjour,

    je ne vais pas parler ici d'un bout de code en particulier mais d'une façon de programmer en php.

    Objectif : Construire un routeur pouvait être réutilisé d'un projet sur l'autre.

    Ce que j'ai déjà fait :

    .htaccess

    RewriteEngine On
    
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php?url=$1 [NC,L]

    index.php

    <?php
    if(isset($_GET['url'])){
      require_once('classes/Autoloader.php');
      Autoloader::register();
      $Routeur = new Routeur($_GET['url']);
      $Routeur->run();
    }
    else{
    echo 'la homepage';
    }

    Point de blocage :

    Je tiens à faire les choses par moi même donc sans framework, composer et autres bibliothèque.

    Voici ma logique qui est aussi mon point de blocage :

    Class Routeur{
    	
    public $_url='';
    	
    public function __construct($url){
      $verif = $this->verification($url);
      if(count($verif) > 0){
        $this->_url = $verif;
      }
    }
    	
    private function verification($urlAvantVerif){
      $Route = new Route($urlAvantVerif);
    
      return $Route->_routes;
    }
    	
    public function run(){
      if($this->_url !== ''){
        $controller = $this->_url[0];
        if(file_exists('controller/controller'.ucfirst($controller).'.php') == true){
          if($controller == 'erreurs'){
            require_once('erreurs/404.php');
          }
          else{
            require_once('controller/controller'.ucfirst($controller).'.php');
          }
        }
        else{
          header('Location: /erreurs/404');
        }
      }
      else{
        header('Location: /erreurs/404');
      }
    }
    }

    Comme vous pouvez le voir, je compte selon le premier mot dans l'url, appeler mon routeur. Le deuxième mot servant d'action et les mots suivants de paramètres, ainsi un url de type www.monsite.com/personnages/liste/humain aura la logique suivante :

    - J'appelle le controlleur suivant : controllerPersonnages
    - J'appelle la fonction : liste()
    - Dans la fonction liste() qui apparaît dans le contrôleur controllerPersonnage je fais une vérification (si paramètre existe alors on récupère la liste des personnages avec ce paramètre).

    Ma méthode semble cohérente mais demande à ce que je suive rigoureusement ce shéma dans chacune de mes url, qu'en pensez-vous ?

    • Partager sur Facebook
    • Partager sur Twitter
      6 avril 2020 à 10:12:02

      Je te conseil de regarder peut-être cette vidéo :

      https://www.grafikart.fr/tutoriels/router-628

      Après si c'est à titre perso pour l'apprentissage, je suis pour que tu recréer un routeur mais en vrai sur des projets pro le mieux serait d'utiliser des libs qui le font beaucoup mieux que ce que l'on pourrait faire.

      • Partager sur Facebook
      • Partager sur Twitter
        6 avril 2020 à 12:05:27

        En effet c'est pour un projet perso.

        J'avais déjà regardé cette vidéo de grafikart bien expliqué au passage. Ce dernier prend Altorouter seulement dans mon cas j'aimerai pouvoir "réinventer la roue" afin de vraiment tout comprendre.

        Pour le moment comme je le disais dans mon premier poste je vais découper mon url en plusieurs parties :

        1. le contrôleur
        2. l'action reliée à une fonction (qui sera dans le contrôleur) qui préchargera tout le nécessaire -> fonction et méthodes nécessaires au bon fonctionnement de la page
        3. et + : les différents paramétrages que je traiterai avec la fonction en 2.
        4. récupération de la vue selon ce qu'à demander la fonction (avec ou non) les paramètres.

        Cependant je me pose toujours la question des limites de cette méthodes. Bien sûr le mieux c'est de tester par soi-même mais j'essaye d'anticiper un maximum car si je fais tout un projet dessus pour finalement me rendre compte qu'il y a quelque chose de capitale qui ne va pas, ça serait embêtant :)

        Pour l'instant, ce que je trouve gênant c'est le fait que la première partie de l'url va appeler le contrôleur nécessaire et que la seconde partie de l'url soit géré directement dans ce contrôleur.
        Je trouverais ça plus logique que ce soit directement géré par le routeur mais d'un autre côté si je le gère directement depuis le routeur il va falloir que je mette tout mon plan du site dans cette classe ce qui n'est pas pratique/logique car la classe Router doit rester indépendante d'un projet à un autre.

        On dit toujours qu'une image vaut mieux que 1000 mots :

        <?php
        
        require 'vendor/autoload.php';
        
        $router = new App\Router\Router($_GET['url']);
        $router->get('/', function(){echo "Homepage";}0);
        $router->get('/posts', function(){echo 'Tous les articles';});
        $router->get('/article/:slug-:id', "Posts#show")->with('id', '[0-9]+')->with('slug', '([a-z\-0-9]+)');
        $router->post('/posts/:id', function($id){echo 'Poster pour l\'article'. $id . '<pre>' . print_r($_POST, true) . '</pre>';});



        Ici dans cet exemple, ce qui me gêne c'est où je vais mettre cette partie ? Il faut bien qu'elle existe pour pouvoir dirigé correctement l'url saisie vers le bon contrôleur, la bonne fonction.

        J'ai du mal à me voir écrire tout le plan du site sur index.php

        Comme on peut le voir ici il y a déjà 4 lignes juste pour la page principale, la page avec tous les articles, la page d'un article et le post d'un commentaire.
        Alors imaginez si on souhaite créer, modifier, supprimer un article, ou encore modifier, supprimer un commentaire, ajouter un groupe, voir un groupe, etc... bref ça nous fait une belle liste et je ne sais pas si c'est la meilleure solution de l'afficher dans index.php

        -
        Edité par raïzenn 6 avril 2020 à 12:36:01

        • Partager sur Facebook
        • Partager sur Twitter
          6 avril 2020 à 14:46:56

          La solution de devoir suivre une structure ne marche que si tu à tes urls qui sont toujours pareil mais si tu veux une url propre pour du SEO par exemple ça obligerais à faire du rewriting directement sur apache pour ces urls. La solutions du "$router->get" est c'elle qui est utilisé par la très grande majorité des framework et autres. On peut donc ce dire que c'est surement pas trop dégueux :D

          Après pour le placement du code des routes tu peux très bien avoir des require sur un dossier routes par exemples et split les routes comme tu le souhaite. Par exemple un fichier front.php et un fichier admin.php et plus tard si tu fais une api avoir un fichier api.php.

          Je te mets un lien d'un projet de MVC en procédural que j'ai fait il y a un petit moment déjà mais qui peux t'intéresser :

          https://github.com/quenti77/forumDemo

          Architecture qui peut très bien ce faire avec de la POO. Le seul conseil que je pourrais donner c'est de voir le code de framework connu car il n'y a pas mieux pour apprendre mais ça dépend du niveau de la personne et du framework (ou de la lib) que l'on regarde.

          PS: La vidéo de graf sur le router n'est pas celle sur altorouter de la formation php mais une plus ancienne qui montre un router simple.

          PS2: Le site pro sur laquel je travail il y a environ 215 routes que l'on a défini dans 5 fichiers php (site sous laravel)

          -
          Edité par quenti77 6 avril 2020 à 14:56:40

          • Partager sur Facebook
          • Partager sur Twitter
            6 avril 2020 à 18:20:29

            Merci pour le partage de ton projet quenti77.

            J'ai regardé un peu, ce n'est pas totalement en objet (chose que j'essaye de faire) mais la structure reste intéressante !

            J'ai essayé de le mettre sur mon localhost pour voir un peu ce que ça donnait mais je tombe sur des erreurs d'url en mettant local.forum/public/ ou local.forum tout court mais après c'est peut-être parce que je n'ai pas encore trop regardé en détails.

            En revanche oui je souhaite faire le dossier App avec les dossiers controller, models et views. Il faut juste comprendre comment gérer les POST dans ce type de structure mais bon je vais y travailler :)

            • Partager sur Facebook
            • Partager sur Twitter
              8 avril 2020 à 10:58:43

              J'ai revu ma copie !

              En effet, même si la rigueur tiens dans l'url, je me suis rendu compte que la limite se situait là où je ne respectait pas le schéma comme l'url suivant : http://monsite.com/news/ma-premiere-news

              Il faudrait donc que je fasse un url de ce type : http://monsite.com/news/voir/ma-premire-news

              Cela n'est pas trop gênant même si cela donne une indication au hackeur de comment mon site est construit. En revanche cela me pose un problème lorsque je souhaite faire une url pour des interfaces types deep web :  http://monsite.com/monCompte/mesPersonnages/liste

              Dans cette configuration il va chercher le contrôleur monCompte auquel il trouverait la méthode mesPersonnages() et dans lequel liste ne serait qu'un paramètre.

              J'ai donc trouvé une autre méthode :

              if($this->_url !== ''){
                $nbParties = count($this->_url);
              			
                if($nbParties==1){
                  $routing['controller'] = $this->_url[0];
                }
                else{
                  for($i=0;$i<$nbParties;$i++){
                    if(file_exists(APP.'controllers/controller'.ucfirst($this->_url[$i]).'.php') == true){
                      $routing['controller'] = $this->_url[$i];
                      }
                    }
                  }
              
                if($routing['controller'] != 'erreurs'){
                  require_once(APP.'controllers/controller'.ucfirst($routing['controller']).'.php');
                  if($nbParties > 1){
                    $routing['method'] = 'defaut';
                    for($i=0;$i<$nbParties;$i++){
                      while(function_exists($this->_url[$i] === true)){
                        $routing['method'] = $this->_url[$i];
                      }
                    }
                  }
                var_dump($routing);
                }
                else{
                  header('Location: /erreurs/404');
                }
              }

              Cette méthode permet donc de récupérer l'url peu importe s'il a deux controlleurs, ce sera toujours le dernier qui sera pris, permettant ainsi de faire des url de type http://monsite.com/monCompte/maGuilde/listeMembres

              La limite de cette méthode c'est que les url doivent toujours être différentes d'une section à une autre, exemple :

              http://monsite.com/guildes (renvoi le contrôleur "controllerGuildes.php")

              http://monsite.com/monCompte/guildes (renvoi aussi le contrôleur "controllerGuildes.php")

              Et aussi qu'une fonction n'ait pas le même nom qu'un contrôleur mais ça c'est très peu probable :)

              • Partager sur Facebook
              • Partager sur Twitter

              Architecture php

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
              • Editeur
              • Markdown