Partage
  • Partager sur Facebook
  • Partager sur Twitter

URL rewrite, problème d'url et dispatch

Sujet résolu
    10 août 2012 à 8:45:01

    Bonjour,

    J'ai développé un site sur mon poste Windows. Maintenant que je souhaite le mettre en ligne sur un serveur Unix, le rewrite et URL ne fonctionnent plus. Je gère le dispatch des mes URL via un ensemble de méthodes

    Mon fichier .htaccess ne fait que rediriger vers mon fichier index qui lui initialise des variables et fait des includes.

    Dans mon fichier d'index, j'ai positionné des variables :

    define('WEBROOT', dirname(__FILE__));
    define('ROOT', dirname(WEBROOT));
    define('DS',DIRECTORY_SEPARATOR);
    define('CORE', ROOT.DS.'core');
    define('BASE_URL', dirname(dirname($_SERVER['SCRIPT_NAME'])));
    


    L'URL qui ne semble pas bien fonctionner est BASE_URL. Cette variable me permet par la suite de pouvoir faire des URL via les méthodes de ma classe Routeur suivantes :

    /**
        * Permet de générer une url à partir d'une url originale
        * controller/action(/:param/:param/:param...)
         * @param String $url URL
        **/
        static function url($url = ''){
            trim($url,'/');
            foreach(self::$routes as $v){
                if(preg_match($v['originreg'],$url,$match)){
                    $url = $v['redir'];
                    foreach($match as $k=>$w){
                        $url = str_replace(":$k:",$w,$url);
                    }
                }
            }
            foreach(self::$prefixes as $k=>$v){
                if(strpos($url,$v) === 0){
                    $url = str_replace($v,$k,$url);
                }
                return BASE_URL.'/'.$url;
            }
        }
    
        /**
         * Permet de retourner le webroot
         * @param String $url URL
         * @return String URL finale
         */
        static function webroot($url){
            trim($url,'/');
            return BASE_URL.'/'.$url;
        }
    


    Voici des exemples d'appel pour construire mes URL dans mes balises HTML a, attribut href :

    Routeur::webroot('css/default.css')
    Routeur::url("pages/view/id:{$m->id}/slug:{$m->slug}")
    


    L'ensemble de mes préfixes sont construit par le biais de ma classe Routeur :

    class Routeur {
        
        // Routes de redirection
        static $routes = array();
        // Ensembles de prefixes pour l'appel des méthodes des Controllers
        static $prefixes = array();
        
        /**
        * Ajoute un prefix au Routing
        **/
        static function prefix($url,$prefix){
            self::$prefixes[$url] = $prefix;
        }
    
    
        /**
        * Permet de parser une url
        * @param $url Url à parser
        * @return tableau contenant les paramètres
        **/
        static function parse($url,$request){
            $url = trim($url,'/');
            if(empty($url)){
                $url = Routeur::$routes[0]['url'];
            }
            else{
                $match = false;
                foreach(Routeur::$routes as $v){
                    if(!$match && preg_match($v['redirreg'],$url,$match)){
                        $url = $v['origin'];
                        foreach($match as $k=>$v){
                            $url = str_replace(':'.$k.':',$v,$url);
                        }
                        $match = true;
                    }
                }
            }
    
            $params = explode('/',$url);
            if(in_array($params[0],array_keys(self::$prefixes))){
                $request->prefix = self::$prefixes[$params[0]];
                array_shift($params);
            }
            
            $request->controller = $params[0];
            $request->action = isset($params[1]) ? $params[1] : 'index';
            // Gestion du cas ou on a l'action préfixé dans l'URL (hack)
            foreach(self::$prefixes as $k => $v){
                if(strpos($request->action, $v.'_') === 0){
                    $request->prefix = $v;
                    $request->action = str_replace($v.'_','', $request->action);
                }
            }
            $request->params = array_slice($params,2);
            return true;
        }
    
    
        /**
        * Permet de connecter une url à une action particulière
         * @param String @redir URL de redirection
         * @param String @redir URL demandée
        **/
        static function connect($redir,$url){
            $r = array();
            $r['params'] = array();
            $r['url'] = $url;
    
            $r['originreg'] = preg_replace('/([a-z0-9]+):([^\/]+)/','${1}:(?P<${1}>${2})',$url);
            $r['originreg'] = str_replace('/*','(?P<args>/?.*)',$r['originreg']);
            $r['originreg'] = '/^'.str_replace('/','\/',$r['originreg']).'$/';
            // MODIF
            $r['origin'] = preg_replace('/([a-z0-9]+):([^\/]+)/',':${1}:',$url);
            $r['origin'] = str_replace('/*',':args:',$r['origin']);
    
            $params = explode('/',$url);
            foreach($params as $k=>$v){
                if(strpos($v,':')){
                    $p = explode(':',$v);
                    $r['params'][$p[0]] = $p[1];
                }
            }
    
            $r['redirreg'] = $redir;
            $r['redirreg'] = str_replace('/*','(?P<args>/?.*)',$r['redirreg']);
            foreach($r['params'] as $k=>$v){
                $r['redirreg'] = str_replace(":$k","(?P<$k>$v)",$r['redirreg']);
            }
            
            $r['redirreg'] = '/^'.str_replace('/','\/',$r['redirreg']).'$/';
    
            $r['redir'] = preg_replace('/:([a-z0-9]+)/',':${1}:',$redir);
            $r['redir'] = str_replace('/*',':args:',$r['redir']);
    
            self::$routes[] = $r;
        }
    
        /**
        * Permet de générer une url à partir d'une url originale
        * controller/action(/:param/:param/:param...)
         * @param String $url URL
        **/
        static function url($url = ''){
            trim($url,'/');
            foreach(self::$routes as $v){
                if(preg_match($v['originreg'],$url,$match)){
                    $url = $v['redir'];
                    foreach($match as $k=>$w){
                        $url = str_replace(":$k:",$w,$url);
                    }
                }
            }
            foreach(self::$prefixes as $k=>$v){
                if(strpos($url,$v) === 0){
                    $url = str_replace($v,$k,$url);
                }
                return BASE_URL.'/'.$url;
            }
        }
    
        /**
         * Permet de retourner le webroot
         * @param String $url URL
         * @return String URL finale
         */
        static function webroot($url){
            trim($url,'/');
            return BASE_URL.'/'.$url;
        }
    }
    


    Exemple de connect :

    Routeur::connect('pages/:slug-:id', 'pages/view/id:([0-9]+)/slug:([a-z0-9\-]+)');
    


    Pouvez-vous m'aider à comprendre ce que je dois corriger ? Je pense que le problème vient de dirname(dirname($_SERVER['SCRIPT_NAME'])) qui est différent entre Windows en local et Unix sur le web.
    • Partager sur Facebook
    • Partager sur Twitter
      10 août 2012 à 11:27:39

      Affiche le contenu de BASE_URL et vois ce qui diffère, c'est tout.
      • Partager sur Facebook
      • Partager sur Twitter
        10 août 2012 à 23:20:55

        Effectivement c'est ce que j'ai fait.
        • en local sur mon poste il affiche le répertoire de mon site (/repsite)
        • sur le site web, il met juste /. J'ai mon site à la racine de mon ftp


        Dans mes fonction url et webroot, il faudrait peut être que je rajoute une de ces deux variables serveur :
        • $_SERVER["SCRIPT_URI"]
        • $_SERVER["HTTP_HOST"]


        Non ?

        En mettant $_SERVER["HTTP_HOST"] sa fonctionne pas mal les liens. Mais j'ai encore un couac.
        Mon rewrite ne fonctionne pas des masses.

        Voici l'arborescence de mon site :

        ├───config
        ├───controller
        ├───core
        ├───model
        ├───view
        │   ├───configs
        │   ├───errors
        │   ├───layout
        │   ├───medias
        │   ├───pages
        │   ├───posts
        │   └───users
        └───webroot
            ├───css
            ├───img
            └───js
                └───tinymce
                    ├───...
        


        J'ai un htaccess à la racine de mon site :

        Options +FollowSymLinks
        RewriteEngine On
        RewriteBase /
        RewriteRule (.*) webroot/$1 [L]
        


        Et un autre dans webroot :

        Options +FollowSymLinks
        RewriteEngine On
        RewriteBase /
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteRule (.*) index.php/$1 [L]
        


        Dans mon fichier index.php, je fais une instance d'un de mes objets :

        new Dispatcher;
        


        Voici le code du constructeur de ma classe Dispacther :

        function  __construct() {
                // Récupère la requête serveur
                $this->request = new Request();
                // Parse la requête pour récupérer controller, action et params
                Routeur::parse($this->request->url, $this->request);
                // Chargement du controleur
                $controller = $this->loadController();
                $action = $this->request->action;
                
                // Vérification de l'existance d'un prefixe
                if($this->request->prefix){
                    $action = $this->request->prefix.'_'.$action;
                }
                if(!in_array($action, array_diff(get_class_methods($controller),
                        get_class_methods(get_parent_class($controller))))){
                    $this->error('Le controller '.$this->request->controller. ' n\'a pas
                                    de méhode '.$action);
                }
                // Appel de l'action du Controller
                debug($controller);
                debug($action);
                call_user_func_array(array($controller, $action),
                    $this->request->params);
                // Autorender
                $controller->render($action);
            }
        


        Je fais appel à une autre classe Request de mon cru, pour récupérer l'ensemble des paramètres de mon url et c'est là où il y a le couac :

        function __construct() {
                $this->url = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '/';
                
                // Si on a un numéro de page dans l'URL
                if(isset($_GET['page']) && is_numeric($_GET['page'])){
                        if($_GET['page'] > 0){
                            $this->page = round($_GET['page']);
                        }
                }
                if(!empty($_POST)){
                    $this->data = new stdClass();
                    foreach($_POST as $k => $v){
                        $this->data->$k = $v;
                    }
                }
            }
        


        La variable $_SERVER['PATH_INFO'] n'est jamais présente et du coup je ne retrouve pas mes bonnes url. Je retombe à chaque fois sur l'index de mon site car derrière j'ai / à tous les coups :

        $this->url = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '/';
        


        Je ne sais plus quoi faire dans mon code par la suite.

        Pouvez-vous encore m'aider un peu plus ?
        Merci.
        • Partager sur Facebook
        • Partager sur Twitter
          13 août 2012 à 13:56:39

          Salut,

          Pour information, grâce à l'aide d'un pote j'ai résolu mon problème de rewrite.

          Au lieu d'utiliser la variable $_SERVER['PATH_INFO'] du constructeur de ma classe Request, il fallait utiliser $_SERVER['REQUEST_URI'].

          Maintenant mon site fonctionne du tonnerre de Dieu.
          A+
          • Partager sur Facebook
          • Partager sur Twitter
            7 août 2019 à 16:42:09

            Bonjour,

            Je suis navré de déterrer un sujet si ancien, mais il s'avère que je rencontre un problème avec le même code (on a du suivre le même tuto sur Grafikart).

            Sauf que mon soucis n'est pas résolu.

            J'ai écrit les mêmes lignes que lj, tout fonctionne parfaitement en local (sous wamp) et lorsque je bascule en ligne sur OVH, absolument plus rien ne fonctionne. Les liens CSS ne fonctionnent plus (le style ne s'applique pas à la page, alors que dans le code source je peux cliquer sur les liens css et voir le code...), les liens entre les pages ne fonctionnent pas (j'ai un file not found à chaque fois).

            La seule chose qui fonctionne c'est l'affichage d'images avec la balise <img> et

            src="<?php echo Router::webroot('img/monimage.jpg'); ?>"



            J'ai essayé pas mal de choses, sans succès.

            Une idée? ça fait deux ans que je planche sur ce site, c'est dur de galérer si près du but...

            Merci!

            • Partager sur Facebook
            • Partager sur Twitter

            URL rewrite, problème d'url et dispatch

            × 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