How to handle special characters like & and / in .htaccess rules? - php

In my .htaccess file I have defined following rule,
RewriteRule ^([-0-9a-zA-Z]+) search.php?id=$1
The above rule works fine if I am browsing http://example.com/abcd
I need to use the symbols & % - / in the url like: http://example.com/ab&cd
What changes have to be made to the rule for this to work?

No idea how that rule is working for you. First, it loops. Second, there is no capture groups for $2 and $3, but it doesn't matter because $1 is always "search" anyways. I'm assuming you've pasted a partial snippet of a rule that you have that works.
The reason why &, %, or / isn't being matched is because your regex says:
[-0-9a-zA-Z]+
which means: one or more letters, numbers, or a dash. So no &, %, or /. So you can add those into the square brackets:
RewriteRule ^([-0-9a-zA-Z/%&]+) search.php?id=$1&ff=$2&ffid=$3
However, keep in mind that the URI is decoded before any rules get applied. This means if the URI looks like:
/foo%28bar
You don't need to match against %, because the URI gets decoded into:
/foo(bar
and you need to match against (. A better option may to just match against every except dots:
RewriteRule ^([^.]+) search.php?id=$1&ff=$2&ffid=$3
or whatever you don't want in your match.
Try:
RewriteRule ^([^.]+)$ search.php?id=$1 [B]
The difference here is the $ to bound the match to the end of the URI, and the B flag ensures the & gets encoded.

You need to URL encode 'ab&cd' using urlencode
so that & gets turned into %26.
After this, in search.php you'll need to account for it and decode it, using urldecode.

Do the URL like this:
http://example.com/id/ff/ffid
and write your rule around that. Also, why do you need 3 ID parameters? Couldn't you just lookup the other 2 using the first one?

Do with your url
RewriteRule ^directory/([^/.]+)$ /searchpage.php?search_keywords=$1 [L]

Related

Allow percentage (%) symbol in mod_rewrite?

So I'm trying to pass a PHP urlencode() variable through a mod_rewrite rule, but I can't seem to get it working correctly.
Currently I'm passing this sort of thing:
/test/abc%40test.co.uk
The # symbol replaced with the &40 in the urlencode.
Through this rule:
RewriteRule ^test/([-_.%A-Za-z0-9]+)/?$ test.php?variable=$1
As far as I'm aware this should allow the % symbol through; why isn't it working? Am I missing something obvious?
The URL is decoded before it is sent through the rewrite engine, so you need to match against #, and not the encoded string. Try:
RewriteRule ^test/([-_.#A-Za-z0-9]+)/?$ test.php?variable=$1

How to match spaces and ascii characters in .htaccess file

I'm trying to match special characters in my .htaccess file for so an id value can return a page matching the correct id value.
In my MySQL field the text is: Thelma & Louise
Before the rewrite rule page address looked like this with all the property data populating the page www.site.com/movie.php?id=Thelma+%26+Louise
My RewriteRule ^movie/([A-Za-z0-9_-\s]+)/?$ /movie.php?id=$1
The url comes out like this but with a page not found error
www.site.com/movie/Thelma+%26+Louise
How can I properly match the ascii characters so that the page is displayed.
Thanks for any help!
The URI gets decoded before it gets run through any of the rewrite rules, so you need to match against a space and an ampersand &. Your pattern, ([A-Za-z0-9_-\s]+) needs to account for those symbols:
RewriteRule ^movie/([A-Za-z0-9_&+-\s]+)/?$ /movie.php?id=$1 [L,B]
Additionally, you need to use the B flag so that the grouped match $1 gets propery encoded in the query string.
First of all i wouldn't use any ascii characters in my url. Maybe try trimming them so you have thelma-louise or thelma+louise. But thats my personal experience.
Second, you rewrite to your ID with the name of the movie. Can't you do it like this:
movie/([0-9a-zA-Z-]+)-([0-9]+) movie.php?id=$2 so its looks something like movie/thelma-louise-101 Lots of movies have the same name. And now you know that IDS are at least an INT. Don't forget to check in PHP offcourse.
Your second rule probably doesn't match. You could try to put all possible characters in your regex, but it is probably better to match all characters, but the characters you don't want to match. In this case that would probably be the / character:
RewriteRule ^movie/([^/]+)/?$ /movie.php?id=$1
Please note that you still have to make sure you are not creating an infinite loop.

mod_rewrite RewriteRule for abc.php?a=1&b=2 to abc/2.html

I am a real newbie to the either mod_rewrite or Regex.
Therefore I just need your help for the following problem.
I got a PHP-Page that looks just like:
stuff.php?id=1&text=2
I know want to to look like
stuff/2.html
Do anyone of you have the RewriteRule line for the htaccess in mind to let it look just like this?
Thanks a lot in advance!
A rewrite rule for this particular page:
RewriteRule ^stuff/2\.html$ stuff.php?id=1&text=2
And if 2 should be dynamic:
RewriteRule ^stuff/([0-9]+)\.html stuff.php?id=1&text=$1
A little explanation:
^ and $ stand for start and end of the string, so we don't match longstuff/2.html.php.
The dot has to be escaped \. because otherwise it has a special meaning in RegEx ("any character")
the parantheses in the second pattern are a "capture group", their content will be available in the rewrite as $n (with n = number of capture group, in this case 1)
[0-9] is a character class, matches one character of the class, in this case a digit
+ means "one or more"
Here's a rule to redirect stuff/2.html to stuff.php?id=1&text=2
RewriteRule ^stuff/([\d]+)\.html$ stuff.php?id=1&text=$1 [L]
Notice [\d]+ will only accept numbers, if you want to allow letters and caret, use the following rule :
RewriteRule ^stuff/([\w-]+)\.html$ stuff.php?id=1&text=$1 [L]

Apache RewriteRule rule

Alright, I give up. I just can't quite wrap my mind around apache rewrites, I've looked through a lot of the stackoverflow suggestions and none seems to make sense to me.
So, I have a script that current renders content based on www.example.com/index.php?article=some-article-name
But, I want the user to think that page is www.example.com/section/some-article-name
I've tried using stuff like
# Turn on URL rewriting
RewriteEngine On
RewriteRule ^/section/([a-zA-Z0-9\-]+)$ index.php?article=$1
I discovered the answer thanks to the direction of all of these folks.
RewriteRule ^section/([a-zA-Z0-9]+)$ test.php?article=$1
RewriteRule ^section/([a-zA-Z0-9]+)/$ test.php?article=$1
You need both to handle 2 different types of requests, ones with a / at the end and those that don't.
You may want a simpler rule like.
RewriteRule ^/section/(.*) index.php?article=$1
A name like some-article-name will fail because you won't match the hyphen. If you want a limited regex try something like:
RewriteRule ^/section/([-_.a-zA-Z0-9]+)$ index.php?article=$1
This will match ASCII alphanumeric characters along with punctuation most likley to be in the name.
Either of these rules will fail if you have parameters on the incoming request.
Your RegEx is SO close. You have a capturing group ([a-zA-Z0-9]+) that is looking for one or more lower case letters, upper case letters and/or numbers, but what it isn't looking for is a hyphen. Try this:
RewriteRule ^/section/([a-zA-Z0-9\-]+)$ index.php?article=$1
Because the hyphen has special significance in Regular Expressions you need to escape it.

Trouble with URL rewriting in .htaccess

My .htaccess file looks like this:
RewriteEngine On
RewriteRule ^articles/(\d+)*$ ./articles.php?id=$1
So, if the URL foo.com/articles/123 is requested, control is transferred to articles.php?id=123.
However, if the requested URL is:
foo.com/articles/123/
or
foo.com/articles/123/whatever
I get a "404 Not Found" response.
I would like to call articles.php?id=123 in all these cases. So, if the URL starts with foo.com/articles/[digits]... no matter what other characters follow the digits, I would like to execute articles.php?id=[digits]. (The rest of the URL is discarded.)
How do I have to change the regular expression in order to achieve this?
Just don't look for the end:
RewriteRule ^articles/(\d+) ./articles.php?id=$1
You do need to allow the trailing / with:
RewriteRule ^articles/(\d+)/?$
The \d+ will only match decimals. And the $ would disallow matches beyond the end.
If you also need trailing identifiers, then you need to allow them too. Then it might be best to make the match unspecific:
RewriteRule ^articles/(.+)$
Here .+ matches virtually anything.
But if you want to keep the numeric id separate then combine those two options:
RewriteRule ^articles/(\d+)(/.*)?$ ./articles.php?id=$1

Categories