Bonsoir bonsoir,

Lors de l'intégration du site sous OVH, j'ai un problème au niveau du routing (du moins je crois que celà vient de là).

Explication :
Lorsque je clique sur un lien quelconque, celà me redirige vers une page avec écrit "File not found", j'ai suivi correctment le tuto, le site fonctionne bien en local.

En ligne, le dossier blog a été remplacé par la racine du site (/www).
En local : localhost/blog/pages/view/1
En ligne : <site>/pages/view/1

Merci d'avance à toutes aides disponibles, cordialement.

22 réponses


MrGuillou
Réponse acceptée

test avec $_SERVER'REQUEST_URI'] à la place de $_SERVER'PATH_INFO']

Bonsoir,
Tu as bien le htaccess à la racine du dossier www ?

l'url rewriting est-il activé ?

Oui, le .htaccess est bien à la racine du dossier www par contre, comment je peux voir si le rewritting est activé (je pense qu'il l'est, à vérifier) ?

Voici mon .htaccess :
RewriteEngine On
RewriteRule (.*) webroot/$1 [L]

Pour voir si le mod_rewrite est activé en PHP (en supposant que tu n'as pas accès au shell, ce qui serait plus simple), évalue l'expression suivante dans un de tes scripts:

strpos(shell_exec('/usr/local/apache/bin/apachectl -l'), 'mod_rewrite') !== false

Il retourne TRUE si le mod_rewrite est activé.

A priori, il n'est pas activé.
Comment je fais pour l'activer ?

si c'est un dédié, tu lances un terminal en root et tu mets:

a2enmod rewrite

puis

service apache2 restart

Si c'est un shared server, contact l'admin pour lui demander de le faire.

C'est un serveur mutualisé OVH donc je ne peux pas l'activer.
Le plus étrange, c'est que sur un serveur OVH mutualisé, le mod_rewrite doit être activé sauf que lorsque j'execute cette commande :

strpos(shell_exec('/usr/local/apache/bin/apachectl -l'), 'mod_rewrite') !== false

Rien ne s'affiche mais en remplacant par :

strpos(shell_exec('/usr/local/apache/bin/apachectl -l'), 'mod_rewrite') !== true

Cela m'affiche 1

Sinon, voici mes .htaccess à voir s'il n'y a pas d'erreur, celui présent dans le www :

RewriteEngine On
RewriteRule (.*) webroot/$1 [L]

Et celui présent dans le dossier www/webroot :

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

Sinon, en mettant ceci dans le .htaccess du dossier www/webroot, je n'ai plus l'erreur "File not found" sauf que la cela m'affiche tout le temps l'index :

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

Normalement sur du mutualisé OVH la réécriture d'url est activée.

test simple

dans htaccess

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

dans ton index

echo $_GET'url'];
exit;

si il t'affiche blog/first-5 pour l'url http://www.c-flam.fr/blog/first-5 c'est que la réécriture d'url est bien activée

J'ai fais ce que tu m'as demandé, et cela m'affiche bien blog/first-5. Donc, à priori le mod_rewrite est activé mais le problème c'est que chaque lien me redirige vers l'index, pourquoi ? D'où peut bien venir le problème ?

Par contre, j'ai fais un phpinfo() et la ligne Apache/Loaded Modules n'est pas visible donc je ne peux pas voir si le mod_rewrite est activé.

Donc le mode mod_rewrite est activé

remet le htaccess de base

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

et dans l'index

echo $_SERVER'REQUEST_URI'];
exit;

avec le même test

Avec le même test, je me retrouve de nouveau avec un File not found.
Je vais laisser la conf comme ça afin que tu puisse voir de ton côté le résultat obtenu.

Si le mod_rewrite est activé, pourquoi ce test me retourne false :

strpos(shell_exec('/usr/local/apache/bin/apachectl -l'), 'mod_rewrite') !== false

tu dois avoir un fichier router, ou un truc dans le genre. Tu peux le montrer ?

nouveau htaccess

RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]

puis index

echo $_SERVER'REQUEST_URI'];
exit;

Avec le nouveau htaccess, cela m'affiche /blog/first-5.

Voici mon fichier router.php :

<?php
class Router{

    static $routes = array(); 
    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 = Router::$routes[0]'url']; 
        }else{
            $match = false; 
            foreach(Router::$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';
        $request->params = array_slice($params,2);
        return true; 
    }

    /**
    * Permet de connecter une url à une action particulière
    **/
    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']); 

    // Explose l'url
        $params = explode('/',$url);
        foreach($params as $k=>$v){
            // Condition sur les paramètres (seulement s'il y a :)
      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)
    **/
    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){
          //remplace les informations de la forme ":<texte>:" par sa valeur
                    $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; 
    }
    static function webroot($url){
        trim($url,'/');
        return BASE_URL.'/'.$url; 
    }
}

donc remet ton index d'origine, cela devrait fonctionner

avec le htaccess

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]

A tester

Toujours pareil, redirection sur l'index à chaque fois que je clique sur un lien.

Du coup la plus de 404, l'url est bien retournée à ton index (normal), par contre le routeur ne fait pas le boulot.
Faut trouver le moment ou tu actives le routeur. tu dois surement lui donner l'url ou un truc dans le genre. Je connais pas le tuto à grafikart. Mais faut que tu arrives à trouver le moment ou tu récupères l'url de la page

Je récupère l'url dans le request grâce à la variable $_SERVER'PATH_INFO'], voici le code :

<?php
class Request{
    public $url; // url tappée par l'utilisateur
    public $page = 1;
    public $prefix = false;
    public $data = false;

    function __construct(){
        $this->url = isset($_SERVER'PATH_INFO'])? $_SERVER'PATH_INFO'] : "/";

        if(isset($_GET'page']) && is_numeric($_GET'page']) && $_GET'page']>0){
            $this->page = round($_GET'page']);
        }
        if(!empty($_POST)){
            $this->data = new stdClass();
            foreach($_POST as $k=>$v){
                $this->data->$k=$v;
            }
        }
    }
}
?>

Du coups, pourquoi ça fonctionne en local mais pas en ligne ?

Ça marche, merci beaucoup ^_^

La méthode de grafikart n'est plus comptable avec les serveurs apache d'ovh, dommage.

Donc le correctif final est de modifier le htaccess

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]

et la classe Request

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

a la place de

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

Voila voila

Vraiment merci beaucoup MrGuillou
Tu es un champion!!!!