Bonjour,

Pour mon premier post j'espère avoir posté ma question dans la bonne catégorie. :)

Je rencontre un problème avec mon URL Rewriting. Tout fonctionne en local sur mon serveur easyPHP mais dès que je le met en ligne c’est le drame.
Je vous met le contenu de mon fichier htaccess avec l’espoir que vous pourrez éclairer ma lanterne.

Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^realisations\/([a-z\-]+)\/$ realisations.php?projet=$1 [QSA,L]
RewriteRule ^([a-z\-]+)\/$ $1.php [QSA,L]

L’idée étant d’avoir une adresse du type monsiteweb.fr/realisations/nomduprojet/

La première règle de réécriture ne fonctionne plus. J’ai cherché à voir si ma page realisations recevait bien un paramètre en GET mais elle ne reçoit rien.

La deuxième règle fonctionne quant à elle toujours parfaitement.

47 réponses


Essaye avec un / devant realisations.php

RewriteRule ^realisations\/([a-z\-]+)\/$ /realisations.php?projet=$1 [QSA,L]

sinon entraine toi avec ce site

Salut,

Le problème vient sûrement de RewriteBase /. Quel sont tes URLs en local ? En prod ?

james332
Auteur

Huggy, j'avais déjà essayé avec un / devant réalisations.php ça ne change rien.

tleb, mes urls en local sont de type monsite.dev/realisations/monprojet/
et en prod monsite.fr/realisations/monprojet/

Ton .htaccess c'est bien celui à la racine, sous le www ?
c'est là aussi qu'on trouve le realisations.php ?

james332
Auteur

Huggy, oui il est bien dans le répertoire www de mon site et realisations.php y est aussi

Donc en théorie tu n'as pas besoin du rewriteBase
Un conseil, lorsque tu testes, penses à désactiver le cache du navigateur ou bien fait des Ctrl F5 pour être sûr;

james332
Auteur

ok merci, je vais essayer sans rewriteBase et en pensant bien à vider le cache navigateur

james332
Auteur

J'ai vidé mon cache navigateur et je l'ai désactivé sans succès. Je suis même aller vérifier ma règle sur le site que tu m'as donné sans succès.
C'est un véritable mystère :(

Question bête : dans ta regex tu ne prends en compte que les minuscules dans le nom de projet, c'est normal ?

james332
Auteur

oui, tous mes noms de projets sont en minuscule.
En tout cas merci pour ton aide :)

Tu avais plusieurs petites erreurs dans ton .htaccess, qui, ensemble, faisaient que le tout ne fonctionnait pas :

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^realisations/([a-z-]+)/? /realisations.php?projet=$1 [L]
RewriteRule ^(.*)$ /index.php?param=$1 [L]

Alors :

  • Ça m'étonnerai que tu veuilles laisser tes utilisateurs accéder aux dossiers, donc il faut enlever la condition que le dossier n'existe pas.
  • Je ne sais pas pourquoi, mais tu voulais à tout prix tout escape. Ce n'est pas nécessaire.
  • Il vaut mieux que le dernier slash soit optionnel, sinon, si il n'y est pas, la requête plante.
  • Il faut un / au début du match.
  • Le flag QSA est inutile.
  • Tu ferais mieux de match tout le reste et de tout rediriger sur une page php. Cette page interpretera ensuite le paramètre pour répondre correctement : la bonne page, ou 404 si le paramètre n'est pas bon. Ce n'est pas du tout safe de faire $1.php parce que on pourrait remonter dans ton arborescence avec ../ et accéder à des fichiers qui ne devraient pas être accessibles.
james332
Auteur

tleb, j'ai effectué les modifications que tu m'as suggéré mais malheureusement ça ne change rien.

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^realisations/([a-z-]+)? /realisations.php?projet=$1 [L]
RewriteRule ^([a-z-]+)/$ /$1.php [L]

Je met aussi le code de génération du lien, si jamais ça peut aider à trouver la source du problème sachant que j'ai enlevé le / à la fin de l'adresse pour le moment

<a href="/realisations/<?php echo $valeur['id']; ?>"

Par contre tu as bien fait de m'ouvrir les yeux sur le risque de redirection avec ../ je vais revoir le code de mes pages pour intégrer ton conseil.

Tu as oublié le / avant le ?.

james332
Auteur

non je l'ai aussi enlevé dans la génération de l'adresse.
D'ailleurs je viens de m’apercevoir que même en supprimant complétement le fichier htaccess ou en le remplaçant par un vide sur mon hébergement, la règle de réécriture fonctionne toujours.... Y aurai t’il un délai de prise en compte de changement de ces paramètres de configuration par OVH ?

non je l'ai aussi enlevé dans la génération de l'adresse.

# le / avant le ? est nécessaire, sinon c'est le nom de projet qui est optionnel
RewriteRule ^realisations/([a-z-]+)/? /realisations.php?projet=$1 [L]

D'ailleurs je viens de m’apercevoir que même en supprimant complétement le fichier htaccess ou en le remplaçant par un vide sur mon hébergement, la règle de réécriture fonctionne toujours.... Y aurai t’il un délai de prise en compte de changement de ces paramètres de configuration par OVH ?

Ça, c'est le cache de ton navigateur. Si tu vides pas le cache pour faire tes tests, c'est normal que ça ne fonctionne jamais...
Utiliser Ctrl+F5 pour rafraichir sans prendre en compte le cache.

james332
Auteur

rassure toi tleb c'est exactement ce que j'ai fait, j'ai vidé le cache + ctrl + F5 et rien à faire. Je suis même passé sur un navigateur que je n'utilise jamais pour voir

Donnes nous plus d'info, quel hébergeur (oui parfois ça change), les dossiers ...
Au pire tu sais que tu peux débugger le rewriting dans les log en rajoutant ceci

<Directory ....>
...
LogLevel debug rewrite:trace8
</Directory ...>

dans le httpd.conf (marche pas en mutu)

james332
Auteur

Alors je suis sur un hébergement OVH mutualisé d'où une marge de manoeuvre assez limité.
Le site ainsi que les pages principales (index, realisations, htaccess...) sont à la racine du répertoire www.
J'ai regardé sur la doc que donne OVH pour la configuration du htaccess, ils donnent comme exemple

RewriteEngine On
RewriteCond %{REQUEST_URI} !testing.php
RewriteRule (.*) testing.php?var=$1

Que j'avais modifé en

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !realisations.php
RewriteRule ^realisations/([a-z-]+)$ /realisations.php?projet=$1 [L]
RewriteRule ^([a-z-]+)/$ /$1.php [L]

Histoire de voir ce que ça pouvait donner sans grande conviction et effectivement ça n'a rien changé

Hello,

En y allant simplement par étape déjà,

RewriteEngine On
RewriteRule .* testing.php

Cela redirige toutes tes urls vers testing.php ? (https://www.ovh.com/fr/g1971.mutualise_htaccess_reecriture_durl_grace_au_mod_rewrite).

Si cela fonctionne, on passera à l'étape 2 :D

james332
Auteur

Salut Elyanor,
je viens d'essayer ta manip et cela fonctione parfaitement, on peu passer à l'étape 2 ;)

Parfait, donc ça prouve juste une erreur :)

Étape 2 :

RewriteRule ^realisations/([a-z\-]+)$   /realisations.php?projet=$1 [L]

Dis-moi simplement si ça passe pour toi seulement pour tes réalisations.

james332
Auteur

Et non c'est là que ça coince :(
D'ailleurs même après avoir supprimé la règle qui permet d'accéder aux autres page sur le htaccess (et avoir vidé mon cache navigateur), la règle fonctionne toujours :(

  • Il ne faut pas escape le -.
  • Il manque /?. Là, l'URL /realisations/foo/ n'est pas valide.
james332
Auteur

j'ai modifié mon htaccess en suivant tes conseils tleb, j'espère avoir fait les bonnes modifications mais ça ne fonctionne toujours pas
Je te met mon fichier htaccess corrigé au cas où j'ai fait une bétise.

RewriteEngine On
RewriteRule ^realisations/([a-z-]+)/?   /realisations.php?projet=$1 [L]
RewriteRule ^([a-z-]+)/$ /$1.php [L]

Voici ce qui marche chez moi

Options +FollowSymLinks
<IfModule mod_rewrite.c>
RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^realisations/([a-z\-]+)/?$   /realisations.php?nom=$1 [L]
</IfModule>

comme l'a dit @tleb, le /?$ permet de mettre ou non le / après le nom du projet
http://monsite.fr/realisations/superprojet
ou
http://monsite.fr/realisations/superprojet/

Pourtant, ce site me dit que :

RewriteEngine On
RewriteRule ^realisations/([a-z-]+)/?   /realisations.php?projet=$1 [L]

sur l'URL http://example.org/realisations/fo-o/ donne bien http://example.org/realisations.php?projet=fo-o.

Tu as un problème quelque part.

james332
Auteur

Huggy, tout fonctionne normalement chez moi aussi en local mais en prod c'est le drame. J'ai quand même essayé avec ton htaccess à tout hasard sans succès non plus.
Effectivement tleb, d'après ton site (comme d'autre que j'avais déjà essayé) mes règles fonctionnent.
Je sèche vraiment là, je vois pas d'où pourais venir le problème

En tout cas, merci à tous de m'aider à essayer de trouver une solution à mon problème. J'espère qu'on trouvera le pourquoi du comment ;)

J'espère que tu ne butes pas sur une histoire de minuscules/majuscules, ça serait ballot

james332
Auteur

effectivement ça serait ballot, mais non, j'ai tout mis en minuscule pour éviter ce genre de problème

c'est sûrement dû à la config d'apache. Enfin je dis ça, sans même vraiment creuser un peu plus le problème... mais bon souvent quand tout fonctionne en local, et quand on balance en ligne on recontre de sérieux problème. la config en local n'est pas tout a fait pareil que celle qui est chez ton hébergeur. (si tu biensûre tu passes par un hébergeur)

Dans ton arboressence, tu n'aurais pas un sous-dossier realisations ?
dans ce cas apache cherche un .htaccess dans ce sous-dossier

james332
Auteur

Kivivi, oui c'est ce que je pense aussi. Ne connaitrais tu pas un moyen de vérifier la configuration apache d'un hébergement mutualisé et quoi chercher ?
Huggy, non je n'ai pas de sous dossier portant ce nom. La page réalisations.php s'affiche (certainement grace à la 2ème règle) mais ne récupère pas les arguments

le Module rewrite doit etre actif, et cela m'étonne que cela ne soit pas actif.

sinon je viens de relire ton .htaccess
Voici ma version pour t'aider après c'est a essayer.
En fait je viens de voir que tu as oublié de mettre le slash entre astérics et realisation à RewriteEngine

Options +FollowSymlinks 
RewriteEngine On 
.......
...........
RewriteRule ^/realisation/([a-z0-9\-]+)/$ /realisations.php?projet=$1 [L]

Essai voir Merci

james332
Auteur

Kivivi, j'ai fait ta modification pour voir mais ça ne change rien :(
Comme sugéré dans des posts précédents, je me demande si il n'y a pas des spécificités dans la configuration du serveur Apache de mon hébergeur par rapport à la configuration de base d'EasyPHP. Dans ce cas il y a peut être une syntaxe particulière à appliquer même si d'après l'aide d'OVH je devrais être bon.

Salut James,

Est-ce que tu as pu résoudre ton problème ?
J'espère que oui parce-que ça fait un moment ^^

Sinon, j'ai tellement galéré moi aussi pour la réécriture d'URL, que j'aimerai t'aider.
J'ai lu toute la conversation et je suis d'accord avec tout SAUF que moi je pense que dans le RewriteRule
il ne faut pas mettre de slash devant la partie de droite.

RewriteRule ^partie_de_gauche$ partie_de_droite [L]

Je pense que c'est ça le problème, je dirai que si tu met le slash easyphp va aller ici :

ton_disque_dur/[...]/www/realisations.php

et ça plante parce-qu'il fallait aller ici :

ton_disque_dur/[...]/www/ton_site/realisations.php

Moi j'aurai fais comme ça :

1)
J'ai cru comprendre que ton arrboressence ressemble à ça ?

www/mon_site/.htaccess
www/mon_site/realisation.php

Dis moi si je me trompe.
Ensuite, je vois que tu veux accéder à ton site avec ce type d'URL :
monsiteweb.fr/realisations/nomduprojet/

2)
quand tu clic sur un lien de ton site, le lien doit avoir ce type de href :

href="realisation/nom-du-projet"
// pas de slash devant (important)
// tu peux mettre un slash derrière (pas obligé **SI** on pense à gérer son abscence/présence dans le RewriteRule, ce qu'on va faire)

3)
ce lien passe par le .htaccess, le RewriteRule doit être de ce type :
(Fais bien attention au détails, je commente pour ne rien laisser passer)

RewriteRule ^realisations/([a-z0-9-]+)/?$ realisations.php?projet=$1 [L]
// pas de slash au début
// n'échappe pas le dernier tiret dans [a-z0-9-]
// avant de finir par le "$" n'oublie pas "/?" (c'est pour l'abscence/présence du slash dont on parlait section 2))
// fini par le $
// PAS de slash devant la partie de droite (realisations.php?projet=$1)

Une dernière remarque :
Est-ce que "realisations" est bien au pluriel ? J'ai vu un copié/collé de code qui était au singulier.
Vérifie aussi le fichier "realisations.php", qu'il soit bien au pluriel. C'est con mais les histoires où on ne comprend rien ça vient souvent d'une bêtise ^^

J'espère qu'en fait c'était ton hébergeur qui merdait et que tu as déjà tout résolu depuis longtemps ^^

james332
Auteur

Salut SLK, désolé pour la réponse tardive.
Non je n'ai toujours pas résolu mon problème :(, j'ai mis cette partie en attente pour pouvoir continuer a avancer sur d'autre projets en attendant de pouvoir trouver une solution.
Je vais lire attentivement ton post et essayer toutes les modifications que tu m'as indiqué. Je pense que le problème vient de mon hébergeur mais ça ne coute rien d'essayer ;)

il faut que tu crées un routeur et parser les urls sinon l'url rewriting est un peut dérangent à modifier tout le temps avec les htaccess

attention l'hébergeur n'a rien à voir avec la manière dont l'url s'affiche.

Salut Moussa Ball,

Qu'est-ce que tu veux dire ? Ça m'intéresse.
Moi j'ai un routeur, j'essaie de comprendre comment transformer, le travail que fait le .htaccess, pour le mettre dans le routeur.
Mais j'ai l'impression qu'au lieu de mettre à jour le .htaccess à chaque nouveau lien, il faudra mettre à jour le routeur à chaque nouveau lien, et du coup aucun intérêt, mais j'ai sans doute mal compris comment faire, c'est pour ça que je demande. ^^

Sinon James, très concrètement je te montre ce que j'ai chez moi, et qui fonctionne.

Je suis sur windows avec xampp.
Le dossier "root" de xampp est :

C:\xampp\htdocs

Moi j'ai créé un dossier "work" pour mettre tous mes sites dedans (des sites de tests en local)
Donc mon site est ici :

C:\xampp\htdocs\work\monSite

Je donne aussi l'emplacement de mes 2 fichiers qui gèrent les liens :

...\work\monSite\public\index.php
...\work\monSite\.htaccess

Quand je veux donner un lien absolu vers l'accueil de mon site je dois mettre :

<a href="/work/monSite/Accueil">Accueil</a>
// notons qu'il y a un slash au début (chemin absolu, depuis le répertoire "root" de mon serveur)

Comme je vais répéter "/work/monSite/" dans TOUS mes liens, j'utilise un define :

define('BASE_URL', '/work/monSite/');

Donc quand j'écris un lien sur mon site, je met :

<a href="<?= BASE_URL ?>Accueil">Accueil</a>

et mon .htaccess :

Options +FollowSymlinks
RewriteEngine on
RewriteRule ^Accueil/?$     public/index.php?p=general.home [L]
// notons qu'il n'y a pas de slash au début, ni pour Accueil, ni pour public/index...

J'essaie de décortiquer la véritable action que se cache derrière ce RewriteRule :
1) on a envoyé au .htaccess un lien absolu (TOUJOURS en absolu), le lien était :
<?= BASE_URL ?>Accueil
donc :
repertoireRoot_du_serveur/work/monSite/Accueil
2) le RewriteRule va REMPLACER :
"Accueil" (ou "Accueil/")
par :
public/index.php?p=general.home

donc au final on aura le lien :
repertoireRoot_du_serveur/work/monSite/public/index.php?p=general.home

Et ça fonctionne bien.

Courage James ! ^^
Je suis curieux de savoir s'il y avait une couille dans un des rouages ou si c'était l'hébergeur, et dans ce cas le nom de l'hébergeur ?

PS : l'hébergeur n'a rien à voir avec la manière dont l'url s'affiche, mais il peut bloquer l'URL Rewriting.
Mais je serai vraiment étonné, je pensais pas que ça existait encore des hébergeurs sans URL Rewriting xD

à vrai dire l'hébergeur active le module rewriting mais à propos de l'url, c'est le routeur qui fait tout.
le routeur indique quelle controlleur à inclure et c'est le controlleur qui fait son job.
Si tu veut mieux comprendre tu n'a qu'a télécharger sur github un structure mvc en php.
Attention on ne modifie pas à chaque fois le routeur. On le découpe l'url en trois parties dans un tableau associatif puis on le donne à un objet dispatcher enfin lui aussi le donne à un objet appellé controlleur principale qui inclue le bon controlleur et le view

Ah oui je vois ce que tu veux dire.
On choisit un "formatage" pour toutes les URLs de son site, comme ça le Router sera capable de les découper en suivants des règles qu'on lui donnera.
On envoie donc au routeur une URL de type (par exemple) :
admin.users.delete&id=4
Le routeur est codé de façon à comprendre qu'il faut utiliser le controller "users" situé dans la partie "admin", et lancer l'action "delete" avec comme parametre "4".
Ce qu'on fait ci-dessus avec le router est très bien. Mais j'ai l'impression que tu as mal compris l'intérêt de l'URL Rewriting.
Parce-que maintenant que notre router fonctionne bien, on aimerait EN PLUS, modifier l'apparence des URLs qui s'affichent dans le navigateur des clients.
Ce qui permet d'avoir une meilleure sécurité, et un meilleur référencement par les moteurs de recherche. (et le petit plus : c'est plus joli à regarder qu'une url avec des "?=" et "&=" partout).
Et c'est quelque chose que notre router ne peut pas faire, on doit passer par l'URL Rewriting.

Moi je crois qu'il doit mettre en place un système de structure mvc d'un vrai site y'en a un tuto sur ce site le titre c'est développer un vrai site.
oubien jette un coup d'oeil sur [https://github.com/donal/mvc]() ou [https://github.com/phalcon/mvc]()
Ce que tu me dit l'a en générale les sites web le font en php par exemple le noyaux(Dispatcher = Objet Générale du site web) prend l'url l'a donne au router et ce dernier dit quelle controlleur a charger puis le controlleur étant un objet demande quelle vue ou view en anglais à afficher. Malheureusement pour mettre en place une telle structure sa prend du temps et la plupart des sites utilisent des frameworks comme openclassrooms eux il utilise symfony de même que ce site utilise le framework ruby on rails et y'a d'autre zend framework laravel etc... les frameworks font toute le structure de votre site web + la sécurité.

Ah... Non mais on est d'accord, un framework c'est super. Personnellement je n'ai essayé que Symphony2 (il y a un moment) et RubyOnRails, et J'ai aimé les 2 (quand je suis revenu dessus plus tard avec du recul). Avec peut-être un léger coup de coeur pour RubyOnRails parce-que ça m'a permis de découvrir Ruby que j'ai trouvé fascinant. Sachant que les seuls langages non-WEB que je connaissais étaient C, C++, et Java.

En fait ce que tu voulait dire c'était :
"Arrête de t'embêter avec l'URL Rewriting et passe sur un Framework, il gère l'URL Rewriting, entre autres".

C'est pas faux, mais ça ne répond pas à la question du sujet quoi...

Moi je pense que c'est un excellent exercice de coder un site sans Framework, ça permet de bien en comprendre les mécanismes.
Je dis ça parce-que moi j'étais passé du procédural, à Symphony, et j'étais bien largué... Je ne faisais que suivre des instructions sans savoir ce que je faisais. J'usqu'à en avoir ras le bol, arrêter complètement et tenter d'apprendre le pattern MVC en développant un site sans utiliser de Framework.
Ça m'a énormément aidé à comprendre.
Je me suis entraîné à construire un petit site avec MVC, Router, Droits utilisateurs, URL Rewriting, etc. Tout ça sans Framework.

Du coup quand j'ai commencé RubyOnRails j'étais très à l'aise pour le prendre en main.
Bien que pas si évident que ça en fait xD
Si quelqu'un veut se lancer dans RubyOnRails, faîtes le sérieusement. C'est à dire avec une formation professionnelle, ou avec de bons bouquins. Parce-que RubyOnRails utilise des "conventions" (parfois bien à lui) plutôt que des "configurations".
Du coup il se passe souvent des choses un peu "magique" sans qu'on sache d'où ça vient.
Si on ne connait pas ses "conventions" ça devient vite galère...
Mais à la fin, c'est un gros plus, particulièrement pour les gros projets.

+1 pour "conventions = magie"

james332
Auteur

Bonsoir à tous, encore merci pour vos idées.
J'ai dut mettre entre parenthèse ce projet pendant quelques temps mais me revoilà.

Pour répondre à SLK, ma partie droite n'a pas de slash, j'avais essayé d'en mettre un au cas où mais sans grande conviction pour la raison que tu évoques.
1) Tu as raison mon arboressance correspond à ça
2) j'ai effectué la modification dans mon code html pour enlever le slash avant "realisations" dans mon lien sans succès.

Comme je l'avais dit dans un post précédent, ce que je ne comprends pas c'est pourquoi mon hébergeur conserve les règles de l'urlrewrinting même après avoir supprimé le fichier et être passé en mode développement pour désactiver le cache. J'en suis à me demander si il prend en compte les modifications au niveau de mon fichier .htaccess

Je ne désespère pas trouver la solution et, en parallèle, j'ai commencé à développer un petit routeur pour mon site en espérant que ça me permettra de contourner le problème.

Salut,

2) j'ai effectué la modification dans mon code html pour enlever le slash avant "realisations" dans mon lien sans succès.

Non justement il faut bien mettre tes liens en absolu dans le code HTML

<a href="/Realisations/mon/super/lien">Lien</a>

C'est une bonne idée le routeur, bon courage.

james332
Auteur

Je vais les remettre alors ^^