Problèmes d'URL rewriting combiné avec PHP + erreurs apache

WRInaute occasionnel
Depuis ce matin, je tente de faire quelque chose avec l'URL rewriting : je voudrais rediriger toutes les requêtes vers des fichiers non PHP vers le fichier afficher.php. J'ai donc modifié mon fichier .htaccess en ajoutant la ligne suivante :
Code:
RewriteRule !(^.*\.php) afficher.php?fichier=%{REQUEST_FILENAME} [L]

J'ai fait des essais, et ça marche un peu. Mais ça cause aussi beaucoup de problèmes.
Dans le fichier afficher.php, je récupère en paramètre le nom du fichier d'origine, je fais un traitement basé là-dessus, puis je renvoie le contenu au visiteur (oui tout de même c'est mieux :wink: ).
Mais avec ce système, ma gestion des erreurs 404 et autres ne fonctionne plus, et lorsque le visiteur accède à une adresse du genre : http://www.example.com/dossier ça crée des problèmes pour récupérer en PHP le nom réel du fichier qui aurait dû être servi par Apache. Alors je teste si c'est un dossier, je rajoute un /, puis je teste l'existence d'un fichier : index.html, index.htm puis index.php
Si aucun des trois précédents n'existe, je renvoie une erreur 404, mais pas ma page d'erreur personnalisée :
Code:
header('HTTP/1.0 404 Not Found');
Je n'ai pas compris comment je pouvais faire mieux.

Conclusion, c'est un peu le bazar cette première tentative. :cry:

Si vous avez une suggestion pour améliorer tout ça, n'hésitez pas.

Merci.

Jocelyn
 
WRInaute occasionnel
Bon, personne n'a répondu à mon message.
Tout le monde est certainement trop absorber à observer la mise à jour de Google.

J'ai amélioré un peu mon code dans le .htaccess :
Code:
RewriteCond %{REQUEST_FILENAME} -F
RewriteRule !(^.*\.php) afficher.php?fichier=%{REQUEST_FILENAME} [L]
La ligne RewriteCond indique que l'URL ne doit être réécrite que si le fichier est un fichier existant, y compris par une règle d'URL rewriting.
J'ai fait quelques tests, ça semble fonctionner, j'ai "retrouvé" mes pages d'erreurs personnalisées maintenant (erreur 404, 401 notamment). Je vais continuer à tester, et vérifier qu'il n'y a pas de faille de sécurité, puis je mettrai en oeuvre sur tout le site si tout va bien.

----

Je viens de corriger une erreur dans le code pour RewriteCond : l'option -F ne doit pas être entre crochets, d'après la doc. J'ai confondu avec les flags pour RewriteRule qui eux sont entre crochets.

J'ai également tenté le code suivant :
Code:
RewriteCond %{REQUEST_FILENAME} -F
RewriteRule !(^.*\.php) afficher.php?fichier=%{LA-U:REQUEST_URI} [L]
Mais ça ne fonctionne pas mieux. Je n'ai pas l'impression que ça m'est utile dans mon cas.
Mon problème est le suivant : si on accède à http://example.com/dossier/, en temps normal Apache va lire la directive DirectoryIndex pour déterminer quel est le fichier par défaut à afficher (le premier trouvé sera celui qui sera affiché. Sinon, soit un listing de répertoire soit une erreur "accès refusé" seront renvoyés)
Dans mon cas, une requête pour http://example.com/dossier/ va être réécrite en http://example.com/afficher.php?fichier=c:\web\dossier\
Après, je voudrais :
- soit que Apache (par l'intermédiaire de la réécriture dans le fichier .htaccess) indique automatiquement le fichier par défaut à utiliser
- soit que mon script PHP détermine automatiquement quel est le fichier par défaut à utiliser

Dans les 2 cas, je suis coincé... :?

http://httpd.apache.org/docs/mod/mod_rewrite.html
http://httpd.apache.org/docs/misc/rewriteguide.html
http://httpd.apache.org/docs/mod/mod_di ... ctoryindex
 
WRInaute passionné
Jocelyn,

Code:
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteCond %{REQUEST_FILENAME}  -F 
RewriteRule !(^.*\.php) afficher.php?fichier=%{REQUEST_FILENAME} [L]
éviterait ta réécriture dans le cas d'un répertoire, non ?

Dans ce cas tu aurais le traitement par défaut d'Apache.

Dan
 
WRInaute occasionnel
Ca y est, je me suis replongé dans la doc.
En effet, la première ligne que tu proposes de rajouter évite le traitement des répertoires. Hors ce n'est pas ce que je voulais, moi je voulais aussi traiter les répertoires.

Mais bon, une unique ligne de code à ajouter, autant essayer.

Et maintenant, je suis perplexe :!: Contre toute attente, ce code fonctionne ET fait ce que je désirais au début.

Avec mon code :
Code:
RewriteCond %{REQUEST_FILENAME} -F
RewriteRule !(^.*\.php) afficher.php?fichier=%{REQUEST_FILENAME}
Voici ce que j'obtenais dans le fichier afficher.php :
pour contourner le problème j'avais rajouté un bout de code dans afficher.php pour tenter de trouver un fichier index.* dans le répertoire. Mais bon, c'était peu satisfaisant.

Maintenant, avec ton code, Dan :
Code:
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteCond %{REQUEST_FILENAME}  -F 
RewriteRule !(^.*\.php) afficher.php?fichier=%{REQUEST_FILENAME} [L]

D'une manière que je ne comprends pas encore, les requêtes fonctionnent :
une requête pour :
fonctionne dans tous les cas, et la variable $fichier (dans afficher.php) et correctement renseignée :
http://www.example.com/dossier et http://www.example.com/dossier/ :arrow: $fichier = d:/web/dossier/index.html

Dans le cas d'une requête pour http://www.example.com/dossier, d'après ce que j'ai compris de la documentation, il semblerait que Apache fasse une réécriture (ou plusieurs ?) en interne, et au final il tombe sur une URL de fichier et à ce moment seulement la ligne RewriteRule du fichier .htaccess peut entrer en action.

Un grand merci à toi Dan :D

Les voies du mod_rewrite sont parfois impénétrables... 8)

Jocelyn
 
Discussions similaires
Haut