Search code examples
phpmod-rewriteurlencodeampersand

mod_rewrite replace all instances of ampersand with %26 for later


I want to simply not use ampersand in my URL so I can pass ampersands further down into my system when a file is requested. The problem is Apache deals with it differently. I don't know how

I already rewrite the requested file to index.php?url=$1 so I can see what it was, but if it has an ampersand in there, it can't continue past it!

how can I escape the ampersand or turn it into it's hex equal (%26)?

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>`

Solution

  • The proper way to escape ampersand in a query string modified by mod_rewrite is

    %2526
    

    if it's being handled by php.

    When apache rewrites it, it's turned from %2526 to %26 which php then converts into & and stores in the query variable.

    Using the B rewrite rule works too, but then all plus signs in the parameter remain plus signs in php.

    The real world example that I had to face:

    /group/Simon+%26+Garfunkel
    

    With B it rewrites to

    group.php?group=Simon+%26+Garfunkel
    

    and in php you get

    $group="Simon+&+Garfunkel";
    

    when you wanted

    $group="Simon & Garfunkel"
    

    With B you need

    /group/Simon%20%26%20Garfunkel
    

    which works fine.

    without B you get

    group.php?group=Simon%20&%20Garfunkel
    

    and you end up with

    $group="Simon ";
    

    because the & divides query strings.

    But if you double escape

    /group/Simon+%2526+Garfunkel
    

    it rewrites to

    group.php?group=Simon%20%26%20Garfunkel
    

    and you end up with

    $group="Simon & Garfunkel";
    

    like expected.

    If the url is NOT parsed by mod_rewrite into a "clean url", then we can use %26 just fine.