I am always struggling to fix .htaccess files. Can't seem to get all variables parsed and rewritten.

This is my URL structure:

www.domain.com    (index.php)
www.domain.com/basisscholen/   (basisscholen.php)
www.domain.com/basisscholen/plaats/c/  (basisscholen.php > all letters of alphabet)
www.domain.com/basisscholen/plaats/c/city/ (plaats.php)
www.domain.com/basisscholen/plaats/c/city/school/ (school.php > could be any schoolname)

URL and variables in .php files:

"/basisscholen/"     (hard menu link to basisscholen.php)
'.$siteurl.'/'.$type.'/plaats/'.$letter.'/'.$link.'/  (plaats.php)
'.$siteurl.'/'.$type.'/plaats/'.$letter.'/'.$plaatsnaam.'/'.$schoolnaam.' (school.php)

.htaccess file:

RewriteEngine On
RewriteRule ^\.html$ /index.php
RewriteCond %1 !^www$
RewriteRule ^basisscholen/$ basisscholen.php?id=basisscholen
RewriteRule ^basisscholen/plaats/([A-Za-z0-9-]+)/?$ basisscholen.php?letter=$1
RewriteRule ^([^/].*)/plaats/([^/].*)/([^/].*)/?$ plaats.php?type=$1&letter=$2&link=$3 
RewriteRule ^([A-Za-z0-9-]+)/?$ school.php?schoolnaam=$1&plaatsnaam=$2

Can someone tell me what is wrong in .htaccess based on given data?

On last php page I can get only one of the variables with $_GET and that is variable $schoolnaam, so all the pages work up to the last page.


Well there are a couple of problems with your rules.

The problem with your last rule:

RewriteRule ^([A-Za-z0-9-]+)/?$ school.php?schoolnaam=$1&plaatsnaam=$2

This rule will never match an URL like www.domain.com/basisscholen/plaats/c/city/school/. It would match an URL like www.domain.com/hello/ but I guess that's not what you intended.

You could try to use your third rule and just add another group at the end, which would look like that:

RewriteRule ^([^/].*)/plaats/([^/].*)/([^/].*)/([^/].*)/?$ school.php?type=$1&letter=$2&plaatsnaam=$3&schoolnaam=$4

Well don't bother to try that out - it wont work. The reason is the group ([^/].*) tries to match a non-slash and then it tries to match .* (basically "everything"), which obviously includes the slash character. I think what you actually wanted is something like ([^/]+) this matches a non-empty string of non-slash-characters. If you make that change to your third rule and then you can extend it to include the schoolnaam-group.

The final rule-set with my proposed fixes:

RewriteEngine On
RewriteRule ^\.html$ /index.php
RewriteRule ^basisscholen/$ basisscholen.php?id=basisscholen [L]
RewriteRule ^basisscholen/plaats/([A-Za-z0-9-]+)/?$ basisscholen.php?letter=$1 [L,B]
RewriteRule ^([^/]+)/plaats/([^/]+)/([^/]+)/?$ plaats.php?type=$1&letter=$2&link=$3 [L,B]
RewriteRule ^([^/]+)/plaats/([^/]+)/([^/]+)/([^/]+)/?$ school.php?type=$1&letter=$2&plaatsnaam=$3&schoolnaam=$4 [L,B]

Note that I removed your RewriteCond, since it always computes to "true". That's because %1 is undefined - so the expression becomes basically undefined != ^www$ (%1 is a back-reference to the last RewriteCond since there is only one RewriteCond, there can't be a last RewriteCond ergo the backreference will be undefined or empty).

I have also added the L and B modifier to the RewriteRules. The L terminates the processing of rewrite-rules, which is a good default - except you want to chain your RewriteRules.

The B modifier escapes/encodes the backreferences - this is mainly to prevent surprises. Well the only surprise would be that the user can inject his own parameters into your call. This might not be that tragic, but by just adding the B-flag you can eliminate that possibility.

  • I discovered with your help that it is a must to clean up the php code to match the htaccess. Also one last question to this matter. If I make a subdomain for mobile, and in mobile I use exactly the some url structure, how would the reference to the subdomain folder for mobile be. Just one rule for the mobile, and then it follows the rest of the htacces file??? Sep 22 '13 at 10:41

Not the answer you're looking for? Browse other questions tagged or ask your own question.