Conflit entre 2 règles de ré écriture d'URL ?

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour, j'aurai besoin d'un conseil SVP, pour avoir des URL "propre".

Pour l'affichage de mes articles, j'ai un fihier article.php qui sert à afficher les article en récupérant de la BDD, les titre, les contenus… des articles. J'ai déjà cette règle de ré-écriture d'URL :

1
RewriteRule ^([a-z0-9\-]+)$ article.php?url=$1 [L]

Pour que l'URL soit par exemple :

1
article-test

au lieu de :

1
article.php?url=article-test

ça fonctionne.

Mais en fait, pour l'affichage de mes pages (avec un fichier page.php), je souhaiterai avoir le meme principe. Je souhaiterai que mes URL soient par exemple :

1
page-test

au lieu de :

1
page.php?url=page-test

j'ai donc essayé cette règle de ré-écriture d'URL :

1
RewriteRule ^([a-z0-9\-]+)$ page.php?url=$1 [L]

Mai ça ne fonctionne pas. J'ai l'impression qu'il y a un conflit entre ces 2 règles de ré-écriture d'URL.

Est-ce normal? y a t-il une solution SVP? Merci

Édité par Coyote

+0 -0
Staff

Cette réponse a aidé l'auteur du sujet

C'est normal, les deux règles utilisent la même expression régulière.

Il faut donc soit utiliser un marqueur propre à chaque règle (comme une chaîne fixe qui différencier les articles des pages), soit utiliser une seule réécriture mais déterminer en PHP s'il s'agit d'un article ou d'une page (donc faire potentiellement 2 requêtes au lieu d'une), soit regrouper les articles et pages pour les considérer de la même façon (un peu comme WordPress fait).

Édité par viki53

Auteur du sujet

Ok merci beaucoup.

Il faut donc soit utiliser un marqueur propre à chaque règle (comme une chaîne fixe qui différencier les articles des pages)

Je pense que c'est + ce qu'il me faut. As tu un exemple STP, car je ne vois pas trop de quoi tu parles (je suis "débutant").

soit utiliser une seule réécriture mais déterminer en PHP s'il s'agit d'un article ou d'une page (donc faire potentiellement 2 requêtes au lieu d'une)

Comment puis-je faire ceci? Car je ne vois pas comment en PHP je peut faire.

Merci

Édité par stephweb

+0 -0
Staff
1
2
RewriteRule ^article-([a-z0-9\-]+)$ page.php?url=$1 [L]
RewriteRule ^page-([a-z0-9\-]+)$ page.php?url=$1 [L]

Ou

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<?php
$article = $pdo->query('SELECT * FROM articles WHERE slug = "toto"')->fetch();

if (!empty($article)) {
    // C'est un article
}
else {
    // C'est une page
    $page = $pdo->query('SELECT * FROM pages WHERE slug = "toto"')->fetch();
}
Auteur du sujet

Ok merci. pour ton 1er exemple, ça va me donner des URL comme ceci:

1
2
3
4
article-url-test
page-url-test
Alors que moi je veux ceci:
url-test

Je pense que ton 2ème exemple est celui qui me convient le mieux. Merci pour ton aide

+0 -0
Auteur du sujet

Bonjour, pour conclure, du coup ce que je souhaiterai faire, c'est pour les URL de mes pages, avoir ceci par exemple (juste le slug):

1
www.site.com/urltest

et pour les URL de mes articles avoir ceci par exemple (id de l'article + le slug):

1
www.site.com/12-urltest

Est ce possible svp?

Pour mes pages, j'ai cette règle dans mon htaccess:

1
RewriteRule ^([a-z0-9\-]+)$ page_post?url=$1 [L]

ça marche

Pour mes articles, j'ai cette règle dans mon htaccess:

1
RewriteRule ^([0-9]+)-([a-z0-9\-]+)$ article_post?id=$1&url=$2 [L]

mais ça marche pas…

Par contre si j’enlève ma règle de ré-écriture de mes pages, la règle de ré-écriture de mes articles fonctionne…

Pourquoi ? Je ne comprend pas pourquoi vu que mes 2 règles de ré-écritures sont différents…

Merci beaucoup

+0 -0
Auteur du sujet

Pardon j'ai rien dit… j'ai fait une gaffe… Oui maintenant que j'ai inversé leur ordre ça fonctionne. je suis surpris que dans un ordre sa marche, et pas dans l'autre ordre. Merci beaucoup

+0 -0

Le flag Last n'a rien à voir parce qu'ayant un .htaccess, même avec Last on retombe sur le même répertoire après réécriture donc les mêmes règles.

Comme Apache lit et considère les règles de haut en bas, vu que le motif ^([a-z0-9\-]+)$ comprend ^([0-9]+)-([a-z0-9\-]+)$, si tu ne mets pas le second avant l'autre, il est normal qu'il ne soit jamais reconnu au profit du premier. Pour limiter les effets du conflit, il faut donner priorité au second motif en le plaçant avant.

On obtiendrait la même chose avec n'importe quel langage :

1
2
3
4
5
6
$path = lrtrim($_SERVER['REQUEST_URI'], '/'); # ou peu importe
if (preg_match('~^([a-z0-9-]+)$~', $path) {
    // 1
} else if (preg_match('~^([0-9]+)-([a-z0-9-]+)$~', $path)) {
    // 2
}

Vu que le motif testé en 1 est plus "large" qu'en 2, les chaînes qui matchent 2 satisferont d'abord celui en 1. On entrera donc jamais dans le else if à moins d'inverser les 2 cas.

Édité par vibrice

+0 -0
Auteur du sujet

oui c'est vrai. ce que je voulais dire, c'est que ça me parai très difficile de faire proprement cohabiter ces 2 règles ensemble quelque soit l'ordre.

Du cou je vais utiliser ces règles:

1
2
3
4
5
# => re-écritures d'url pour les pages en GET
RewriteRule ^([a-z0-9\-]+)$ post_page?url=$1 [L]

# => re-écritures d'url pour les articles en GET
RewriteRule ^article/([a-z0-9\-]+)$ post_article?url=$1 [L]

Et en PHP, j'interdit les admin de mettre les slash "/" dans les slugs, comme ça, il ne devrai jamais y avoir de conflit entre ces 2 règles de ré-écriture. Merci

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte