Recently I have encontered a strange problem about urlencode, I happened to have a "+" in my both pathinfo and querystring parts of the url.

For exampele:

http://example.com/A + B?s=C + D

I use tamperdata in firefox and can make sure thant firefox has encoded the url to the following:


While on the server side, I have apache url rewrite enabled with the following instruction:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

Then, in php, I got the following:

$_REQUEST['q'] = 'A   B';
$_REQUEST['s'] = 'C   D';
$_SERVER['QUERY_STRING'] = 'q=A + B&s=C%20+%20D';

As we known, the php will automatically use urldecode to parese query string to $_REQUEST super variable, that explains why 'A + B' became 'A B' and 'C + D' became 'C D'.Then, I relize that apache url rewrite has to decode all the characters in order to do the rewirte mapping. FLAG B will help reencde them after mapping.So the rewrite rules became following with B FLAG applied.

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ index.php?q=$1 [B,L,QSA]

Then,the resuelt became:

$_REQUEST['q'] = 'A + B';
$_REQUEST['s'] = 'C   D';
$_SERVER['QUERY_STRING'] = 'q=A+%2B+B&s=C%20+%20D';

What I expected is the follow:

$_SERVER['QUERY_STRING'] = 'q=A%20+%20B&s=C%20+%20D';

Then, I could use rawurldecode mannully parse the query string the the following, also this is how firefox originally

$_REQUEST['q'] = 'A + B';
$_REQUEST['s'] = 'C + D';

But instead apache mod-rewrite B glag make q became 'A+%2B+B' which is differently from the original firefox's encoding 'A%20+%20B'.Of course, apache's encode is compatible withe php urlencode function.

So the question is why firefox and apache behave so differently?Why firefox does not encode 'A + B' to 'A+%2B+B' as common use but 'A%20+%20' which cause so many incompatible with the PHP and the server side?


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy