Home > other >  Multiple hyphen handling (URL rewriting) in .htaccess
Multiple hyphen handling (URL rewriting) in .htaccess

Time:01-21

It gives me URLs like that : http://localhost/service-brussels/ (service is the key and brussels its place). This URL works perfectly.

But, when I type this URL : http://localhost/service-new-york/ it doesn't works anymore. The cause of the problem must be the fact that the place contains several hyphens (new-york) whereas the first one (brussels) contains no hyphens.

Does anyone know how to solve this please ?

RewriteRule ^([a-zA-Z0-9-éçèà] )-([a-zA-Z0-9-éçèà] )$ cities.php?key=$1&place=$2 [L] \  [R=302,L]

In Keys.php

<?php
$seo_keys = array(
'service'=> 'Service',  
'new-service'=> 'New Service'
);
$seo_places = array(
'brussels'=>'Brussels',
'new-york'=>'New York'
);

?>

In cities.php

<?php
 require_once('Keys.php');
$place=$seo_places[$_GET['place']];
$motCle=$seo_keys[$_GET['key']];
?>

I got an error

CodePudding user response:

$seo_keys = array(
'service'=> 'Service',  
'new-service'=> 'New Service'
);
$seo_places = array(
'brussels'=>'Brussels',
'new-york'=>'New York'
);

This is not resolvable in its current form since both "keys" and "places" can contain hyphens and the delimiter you are using between "keys" and "places" is also a hyphen. This is ambiguous, since it's not possible to parse /key-place or /key-place-place or /key-key-place using simple pattern matching (in .htaccess) without prior knowledge of existing keys and places. (It would need to be parsed later in your PHP code by searching for valid keys/places in the array (or database), which is inefficient and could still potentially result in conflicts if a "key" and "place" should happen to overlap. eg. /one-two-three, where one-two is a "key", but two-three is a "place".)

 RewriteRule ^([a-zA-Z0-9-éçèà] )-([a-zA-Z0-9-éçèà] )$ ....

Note that literal hyphens inside a regex character class need to be the first or last character or backslash-escaped to negate their special meaning (as a range specifier).

Note also that this regex does not permit a trailing slash, so it would not seem to match your example URL(s) anyway (that include a trailing slash)? This would then have resulted in a 404, since the rule would not have done anything.

However, I suspect (if the first example URL worked and the 2nd didn't) then your "error" is an E_NOTICE generated by PHP due to an "undefined index". This is because regex is greedy by default so the above regex would have returned service-new and york respectively for your "key" and "place", which don't exist in your lookup arrays. Needless to say, you will need more robust error checking here, since you are accepting raw user input (the URL) so these "errors" are inevitable.

Solution

The easiest/logical solution here is to use a different character as the delimiter, such as a slash, so you would then have URLs of the form:

http://localhost/service/brussels/
http://localhost/service/new-york/

"keys" and "places" cannot contain a slash, so this gets round the obvious ambiguity.

Your rule in .htaccess would then become:

RewriteRule ^([a-zA-Z0-9éçèà-] )/([a-zA-Z0-9éçèà-] )/$ cities.php?key=$1&place=$2 [L]

Note that this forces a trailing slash on the requested URL. If you wish to make the trailing slash optional (although only one URL should be canonical) then you should implement an additonal redirect to redirect to the canonical URL (either with or without the trailing slash).

Aside: Just an observation, but your "keys" appear to be lowercased, but you are permitting uppercased letters in the regex?


Similar/related questions:

CodePudding user response:

This solution is working for me. What do you think?

RewriteEngine On

RewriteRule ^([a-zA-Z0-9] )-([a-zA-Z0-9-] )$ index.php?key=$1&place=$2 [L] \  [R=302,L]

  • Related