web-dev-qa-db-fra.com

La réécriture d'URL Apache ne fonctionne pas

Tous les fichiers .php sont réécrits avant la réécriture ci-dessous:

test.php => test
foo.php => foo

Je veux réécrire cette URL http://www.testdomain.com/test?name=john&id=2&nick=doe en http://www.testdomain.com/test/john/2/doe.

test est le fichier d'index.

J'ai essayé ces méthodes pour réécrire:

  1. Méthode 1:

    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^([^/]+)/([^/]+)/(.*)$ test?name=$1&id=$2&nick=$3 [L,QSA]
    
  2. Méthode 2:

    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^([^/]+)/([^/]+)/(.*)$ test.php?name=$1&id=$2&nick=$3 [L,QSA]
    
  3. Méthode 3:

    RewriteEngine On
    RewriteRule ^([^/]*)/([^/]*)/([^/]*)$ /test?name=$1&id=$2&nick=$3 [L]
    

fichier .htaccess mis à jour contenu:

RewriteEngine On

RewriteRule ^([^.?]+)$ %{REQUEST_URI}.php [L]
RewriteCond %{THE_REQUEST} "^[^ ]* .*?\.php[? ].*$"
RewriteRule .* - [L,R=404]

# RewriteCond %{REQUEST_FILENAME} !-f
# RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{QUERY_STRING} ^name=([\w]+)\&id=([\d]{1,3})\&nick=([\w]+)$
RewriteRule .* /test/%1/%2/%3? [R=301,L]

Tous ne fonctionnent pas (l'URL reste la même, ils ne prennent pas effet)! Qu'est-ce que je fais mal?

3
CS GO

Vous avez mentionné que deux options sont valables pour vous. J'utilise donc la deuxième, http://www.testdomain.com/john/2/doe, et en supposant un .htaccess propre.

RewriteEngine On
# RewriteCond %{REQUEST_FILENAME} !-f
# RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{QUERY_STRING} ^name=([\w]+)\&id=([\d]{1,3})\&nick=([\w]+)$
RewriteRule .* /%1/%2/%3? [R=301,L]

Les lignes commentées qui recherchent des fichiers ou des répertoires peuvent être non commentées, selon votre situation. Supposons qu'une requête sur votre site ressemble à ceci

http://www.example.com/test.php?name=john&id=2&nick=doe

Si vous avez le fichier test.php et que vous décommentez la ligne sur la recherche de fichiers existants, la règle que j'ai écrite échouera à cause de conditions non remplies. Si vous n'avez pas ce fichier, vous pouvez décommenter la ligne. Il en va de même pour les répertoires, bien que plus sûr car je ne pense pas que vous ayez des répertoires avec des extensions.

Les règles ci-dessus transforment

http://www.example.com/test?name=john&id=2&nick=doe

dans

http://www.example.com/john/2/doe

Je l'ai testé sur un serveur virtuel avec Apache 2.2.25 sur Linux.

Vous trouverez ci-dessous le journal de réécriture du test au cas où vous souhaiteriez l’analyser. Le nom du dossier et du serveur virtuel local étant différent, j'espère ne rien avoir modifié pour renommer ces informations.

127.0.0.1 - - [28/Mar/2014:00:03:50 +0800] [www.example.com/sid#cee650][rid#7fe164002970/initial] (3) [perdir /mnt/webs/folder/] strip per-dir prefix: /mnt/webs/folder/test.php -> test.php
127.0.0.1 - - [28/Mar/2014:00:03:50 +0800] [www.example.com/sid#cee650][rid#7fe164002970/initial] (3) [perdir /mnt/webs/folder/] applying pattern '.*' to uri 'test.php'
127.0.0.1 - - [28/Mar/2014:00:03:50 +0800] [www.example.com/sid#cee650][rid#7fe164002970/initial] (2) [perdir /mnt/webs/folder/] rewrite 'test.php' -> '/john/2/doe?'
127.0.0.1 - - [28/Mar/2014:00:03:50 +0800] [www.example.com/sid#cee650][rid#7fe164002970/initial] (3) split uri=/john/2/doe? -> uri=/john/2/doe, args=<none>
127.0.0.1 - - [28/Mar/2014:00:03:50 +0800] [www.example.com/sid#cee650][rid#7fe164002970/initial] (2) [perdir /mnt/webs/folder/] explicitly forcing redirect with http://www.example.com/john/2/doe
127.0.0.1 - - [28/Mar/2014:00:03:50 +0800] [www.example.com/sid#cee650][rid#7fe164002970/initial] (1) [perdir /mnt/webs/folder/] escaping http://www.example.com/john/2/doe for redirect
127.0.0.1 - - [28/Mar/2014:00:03:50 +0800] [www.example.com/sid#cee650][rid#7fe164002970/initial] (1) [perdir /mnt/webs/folder/] redirect to http://www.example.com/john/2/doe [REDIRECT/301]
127.0.0.1 - - [28/Mar/2014:00:03:50 +0800] [www.example.com/sid#cee650][rid#7fe164006990/initial] (3) [perdir /mnt/webs/folder/] add path info postfix: /mnt/webs/folder/john -> /mnt/webs/folder/john/2/doe
127.0.0.1 - - [28/Mar/2014:00:03:50 +0800] [www.example.com/sid#cee650][rid#7fe164006990/initial] (3) [perdir /mnt/webs/folder/] strip per-dir prefix: /mnt/webs/folder/john/2/doe -> john/2/doe
127.0.0.1 - - [28/Mar/2014:00:03:50 +0800] [www.example.com/sid#cee650][rid#7fe164006990/initial] (3) [perdir /mnt/webs/folder/] applying pattern '.*' to uri 'john/2/doe'
127.0.0.1 - - [28/Mar/2014:00:03:50 +0800] [www.example.com/sid#cee650][rid#7fe164006990/initial] (1) [perdir /mnt/webs/folder/] pass through /mnt/webs/folder/john

Mise à jour en fonction de votre commentaire Si vous voulez tester l'URL finale, utilisez ceci:

RewriteRule .* /test/%1/%2/%3? [R=301,L]

Si vous voulez votre fichier d'index, utilisez ceci:

RewriteRule .* /index.php/%1/%2/%3? [R=301,L]
2
PatomaS

J'ai eu une règle similaire, essayez celle-ci:

RewriteEngine On
RewriteBase /
RewriteRule ^test/([A-Za-z0-9-]+)/([0-9]+)/([A-Za-z0-9-]+)/?$ test.php?name=$1&id=$2&nick=$3

Vos liens doivent être:

test.php?name=john&id=2&nick=doe
0
Nicoli

Votre "Méthode 2" me semble appropriée pour correspondre à http://www.testdomain.com/john/2/doe.

Seulement, vous voudrez peut-être essayer d'ajouter le RewriteBase / aussi, quelque chose comme ceci:

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)/(.*)$ test.php?name=$1&id=$2&nick=$3 [L,QSA]

Au lieu de la base, vous pouvez essayer d’ajouter une barre oblique au début de l’expression régulière:

RewriteRule ^/([^/]+)/([^/]+)/(.*)$ test.php?name=$1&id=$2&nick=$3 [L,QSA]
#            ^--- this slash

Vous voudrez peut-être aussi être prudent avec l'indicateur QSA car d'autres paramètres de chaîne de requête seront conservés de cette manière.

Notez que la réécriture de test.php en l'état signifie que ce programme PHP se trouve dans le même répertoire que votre fichier .htaccess. Si ce n'est pas le cas, la réécriture peut ne pas avoir lieu car le module mod_rewrite détecte l'entrée manquante et contourne ainsi automatiquement la règle. Si c'est le cas, cela devrait apparaître dans vos journaux d'erreurs. Sinon, vous devrez peut-être placer un chemin devant le nom du script test.php.

RewriteRule ^/([^/]+)/([^/]+)/(.*)$ /test.php?name=$1&id=$2&nick=$3 [L,QSA]
#            ^--- those slashes  ---^

Notez que nous aurons peut-être besoin d'une copie de vos journaux d'accès et d'erreurs pour voir si Apache vous dit réellement ce qui ne va pas. Vous voudrez peut-être/besoin d'augmenter la verbosité pour obtenir plus d'informations.


P.S. Ce paragraphe semble être inversé ... vous pourriez peut-être modifier votre question et la corriger?

Je veux réécrire cette URL http://www.testdomain.com/test?name=john&id=2&nick=doe en http://www.testdomain.com/test/john/2/doe ou http://www.testdomain.com/john/2/doe.

0
Alexis Wilke

Vous devriez simplement tout rediriger vers votre script, puis le traiter comme suit:

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule (.+) index.php?url=$1 [QSA]

Vous pouvez donc décomposer le $_GET['url'] de / pour obtenir les paramètres individuels.

0
user550