2

I have a rewrite rule in .htaccess

RewriteRule ^page/(.*)$ my-php-page.php?cid=$1

I am passing a encoded string which contains characters like = and + - this is the encoded string;

V1ihnKpip6WpnY7Wm5zn2+6YUtLf2KCh4eKY

When in the complete URL it's

http://www.example.com/my-php-page.php?cid=V1ihnKpip6WpnY7Wm5zn2+6YUtLf2KCh4eKY

now this doesn't work because of the + sign. So I want to send the cid urlencoded which then becomes;

http://www.example.com/my-php-page.php?cid=V1ihnKpip6WpnY7Wm5zn2%2B6YUtLf2KCh4eKY

The + sign becomes %2B. This works great, except when I try this through the RewriteRule in .htaccess - it doesn't work. So the URL would be

http://www.example.com/page/V1ihnKpip6WpnY7Wm5zn2%2B6YUtLf2KCh4eKY

The mypage.php file actually receives the cid as V1ihnKpip6WpnY7Wm5zn2 6YUtLf2KCh4eKY for some reason replacing %2B with a blank space.

Any ideas why it may be doing that? And how can I fix it. Many thanks for the help.

EDIT

I just found this solution - PHP $_GET var with urlencode and "&" bug - but I was wondering if there was a more elegant solution in .htaccess than having to urlencode the string twice?

Community
  • 1
  • 1
Wasim
  • 4,953
  • 10
  • 52
  • 87
  • your rewrite rule starts with `page` but your URL starts with `some-page/` – undone Dec 05 '12 at 10:50
  • No it doesn't, the first 2 URL examples link directly to the PHP file, it doesn't use the rewrite. I've rewritten the question as my examples URL's were a bit confusing. – Wasim Dec 05 '12 at 10:58

2 Answers2

10

Try adding the B rewrite flag. This flag tells mod_rewrite to escape backreferences, the documentation says this:

_rewrite has to unescape URLs before mapping them, so backreferences will be unescaped at the time they are applied. Using the B flag, non-alphanumeric characters in backreferences will be escaped.

Since the % character is reserved for backreferences to groupings matched in RewriteCond statements preceeding the RewriteRule, mod_rewrite treats them differently and could end up attempting to replace the %2 with a blank backreference.

So your rule should look like this:

RewriteRule ^page/(.*)$ my-php-page.php?cid=$1 [B]
Jon Lin
  • 142,182
  • 29
  • 220
  • 220
  • PHP interprets the + as a space, because historically the + was used for spaces in urls before RFC 3986. – Gerben Dec 05 '12 at 21:17
0

If I understood right, to redirect this URL:

http://www.example.com/page/V1ihnKpip6WpnY7Wm5zn2+6YUtLf2KCh4eKY to this one

http://www.example.com/my-php-page.php?cid=V1ihnKpip6WpnY7Wm5zn2+6YUtLf2KCh4eKY

RewriteEngine On
RewriteRule ^page/([^/]*)  http://www.example.com/my-php-page.php?cid=$1 [L]

The result is:

http://www.example.com/my-php-page.php?cid=V1ihnKpip6WpnY7Wm5zn2+6YUtLf2KCh4eKY

with no change in the parameter.

Felipe Alameda A
  • 11,791
  • 3
  • 29
  • 37