I'm trying to create simple rewrite engine to make my urls more beautifull. Currently I'm using this:
RewriteEngine on
RewriteRule ^([a-zA-Z0-9_]*)/?([a-zA-Z0-9_]*)?/?([a-zA-Z0-9\-_/]*)?/?$ index.php?controller=$1&action=$2&id=$3 [NC,L]
So when i enter this url:
www.domain.com/fooo/bar/foobar
i will gete from php:
Array
(
[controller] => fooo
[action] => bar
[id] => foobar
)
I want to update this rewrite rule, so when after domain part of url is starting with 2-3chars it will create different array, like this:
from www.domain.com/eng/fooo/bar/foobar
Array
(
[lang] => eng
[controller] => fooo
[action] => bar
[id] => foobar
)
I created new rule:
RewriteEngine on
RewriteRule ^([a-z]{2,3})/?([a-zA-Z0-9_]*)?/?([a-zA-Z0-9_]*)?/?([a-zA-Z0-9\-_/]*)?/?$ index.php?lang=$1&controller=$2&action=$3&id=$4 [NC,L]
RewriteRule ^([a-zA-Z0-9_]*)/?([a-zA-Z0-9_]*)?/?([a-zA-Z0-9\-_/]*)?/?$ index.php?controller=$1&action=$2&id=$3 [NC,L]
but when i enter www.mydomain.com/english/foo/bar/foobar
it gives me:
Array
(
[lang] => eng
[controller] => lish
[action] => foo
[id] => bar/foobar
)
but I'm expecting
Array
(
[controller] => english
[action] => foo
[id] => bar/foobar
)
because of word "english" being longer than 3chars.
Can someone help me fix this? Thanks!
Your new rule has an optional /
( /?
), so will happily match something which has three letters - ([az]{2,3})
- followed directly by some more letters - ([a-zA-Z0-9_]*)
.
In fact, you have ?
s and *
all over the place in those rules, when as far as I can see you want to check that things are there, not just that they might be .
Try removing the ?
s, and switching to +
(1 or more) instead of *
(0 or more):
RewriteEngine on
RewriteRule ^([a-z]{2,3})/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([a-zA-Z0-9\-_/]+)/$ index.php?lang=$1&controller=$2&action=$3&id=$4 [NC,L]
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([a-zA-Z0-9\-_/]+)/$ index.php?controller=$1&action=$2&id=$3 [NC,L]
If you want to match patterns where only some of the parts are present (eg URLs with 2 parts, not 3 or 4) then simply add separate rules for those.
(As an aside, the form ([some-range]*)?
is redundant anyway, as the *
means "0 or more in the range", and the ?
means "0 or 1 instances of preceding group" - so you have "0 or 1 instances of a group of 0 or more".)
You could use a non capturing group on your first {2,3} block like this to ensure it matches your {2,3} requirement followed by a slash..
(?:([a-z]{2,3})/)?([a-zA-Z0-9_]*)?/?([a-zA-Z0-9_]*)?/?([a-zA-Z0-9\-_/]*)?/?
Group 1 will always contain your two/three character match or be null
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.