views:

306

answers:

4

I've been struggling with this for two days right now.

At the moment I have the following rewrite rule:

RewriteRule ^(.*)$ index.php?u=$1 [NC,L]

Which ports everything behind example.com/ to index.php as the GET variable u. Which is being processed in index.php with an explode to define te different arguments being: the city (between the first slashes) en the location (the second argument)

THis works perfectly for the following urls:

example.com/City/location/ or example.com/City/location
example.com/City/ or example.com/City

Which produces:

$arg[0] = city
$arg[1] = location

The problem happens when the location has an Ampersand in the location name:

example.com/city/location&more

translates to:

index.php?u=city/location&more

The problem is obvious; i can't use the explode parameter in index.php anymore because the second part of the location name is not stored in $_GET['u'].

How can i solve this?

I think of three solutions which i don't know how to implement:
1) rewriting the rewrite rule to split the city and location in the .htaccess
2) using a .htaccess equivalent of urlencode to transform the &-sign to %26
3) a complete other solution:)
Thanx in advance!

Edit Firstly: When the link is being produced by my website it gets translated with urlencode. So there isn't a & where there shouldn't be one. The & is part of a business namen like: "Bagels&Beans" When people want to search that company they type: www.example.com/city/bagels&beans in the url-field. ANd that is where the problem starts.

edit 2 When i go to: example.com/city/bagels%26Beans it translates to the following: $_GET:

Array
(
    [u] => city/Bagels
    [Beans] => 
)

edit 3 The way i explode the $_GET['u'] to form the arguments.

$arg = explode('/',$_GET['u']);
A: 

You shouldn't have & as part of a URL exactly because of this reason. & has special meaning, and should be urlencoded (to %26) any time it is put in an a tag on your site, such that you should never see it actually come in as & in the URL.

Basically, what I am saying, is do not handle this in your htaccess, handle this in whatever bad code is allowing an & to be output as part of a URL.

SoapBox
Everytime i produce the name from the database i urlencode it to %26. But even then it gets wrong -- please look at my edit
blub
+2  A: 

First things first:

example.com/city/location&more

is not a valid query string. You should start query strings with ?, like so:

example.com/city/location?more=value&more2=value2

Second, there is a modifier in mod_rewrite for ensuring query strings get appended to your newly rewritten URLS, which is QSA (meaning append query string). Your rewrite rule would look like:

RewriteRule ^(.*)$ index.php?u=$1 [NC,QSA,L]
cballou
the ampersand is part of the name and not an argument!
blub
@blub: You'd have to encode the ampersand in that case.
Pekka
Take a look at my second edit: even when i encode it to %26 the GET variable goes wrong.
blub
+1  A: 

You could try to use $_SERVER["REQUEST_URI"] instead of the actual $_GET argument.

if(preg_match("%\?u=(.*)$%", $_SERVER["REQUEST_URI"], $Matches)) {
    $Test = explode("/", $Matches[1]);
    var_dump($Test);
}

For "index.php?u=test/testlocation&more" this will output:

array(2) { [0]=> string(4) "test" [1]=> string(17) "testlocation&more" }

sHiRoKKo
+1  A: 

You don’t need to put the URL path in an argument. You can simply parse the original requested path like this:

$_SERVER['REQUEST_URI_PATH'] = strtok($_SERVER['REQUEST_URI'], '?');
$segments = explode('/', trim($_SERVER['REQUEST_URI_PATH'], '/'));

Now all you need is this rule to rewrite the request to your index.php:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^index\.php$ index.php [L]

The additional condition is to only rewrite requests that can not be mapped to existing files.

Gumbo