MOD_REWRITE for URL variables, removing empty parameters and using more than 1field for the first and second variables

我怕爱的太早我们不能终老 提交于 2019-12-18 03:44:24

问题


I have a previous question that was answered very well but requires an amendment and I was unable to reply so have created a new question.

I required a mod_rewrite that made the following:

www.example.com?page=var1&cat=var2&subcat=var3&subsubcat=var4

into this:

www.example.com/var1/var2/var3/var4/

but that also covered the optional use of var2, var3 and var4 so if those variables were empty, it would still work.

The question was answered very well but it requires an amendment to work with different field options for var2, var3 and var4.

The code I have is:

RewriteEngine on
Options +FollowSymlinks -MultiViews

RewriteCond  %{QUERY_STRING} !^page= [NC]
RewriteRule ^([^/]+)/?$ /?page=$1 [L]

RewriteCond  %{QUERY_STRING} !^page= [NC]
RewriteRule ^([^/]+)/([^/]*)/?$ /?page=$1&cat=$2 [L]

RewriteCond  %{QUERY_STRING} !^page= [NC]
RewriteRule ^([^/]+)/([^/]*)/([^/]*)/?$ /?page=$1&cat=$2&subcat=$3 [L]

RewriteCond  %{QUERY_STRING} !^page= [NC]
RewriteRule ^([^/]+)/([^/]*)/([^/]*)/([^/]*)/?$ /?page=$1&cat=$2&subcat=$3&subsubcat=$4 [L]

This works but I need it to be able to make an if-or-else for the choice of what field is being used for what variable and to tell the difference.

For example, if we have the following two strings normally, it is easy to distinguish what field goes for what variable:

www.example.com?page=var1&cat=var2&subcat=var3&subsubcat=var4

www.example.com?othervar1=var1&othervar2=var2&othervar3=var3&othervar4=var4

but for this string, it requires the ability to distinguish what field the variable is for:

www.example.com/var1/var2/var3/var4/

I need the mod_rewrite to choose which is being used.

As well as this, when I actually go to a folder that does exist, it does work correctly. For example, if I go to a folder called "test", which is an actual folder:

www.example.com/test/

it uses it as a variable for the "page" field. If I use the following without the end forward slash:

www.example.com/test 

it outputs the following into the URL:

www.example.com/test/?page=test

I need it to work for folders that exist as normal also.

Please can someone tell me how this can be done? I would appreciate any help in resolving this issue.

Also, can someone tell me what the "-MultiViews" bit means at the beginning as I have not come across this before?

Thank you.


回答1:


OK first the MultiViews options: As per Apache manual:

MultiViews

Content negotiated "MultiViews" are allowed using mod_negotiation.

In short if you have a file called foo.html and if browser requests http://example.com/foo then Apache automatically finds and appends extension and serves foo.html to browser rather than throwing 404. This behavior causes many Rewrite rules to fail hence I disabled it at the start in my answer to your previous question.

Now to exclude real directories from being handled by rewrite rules we'll need an additional condition like this: RewriteCond %{REQUEST_FILENAME} !-d

To support multiple pretty URL schemes:

You have few options here. Please tell me which one you would like to have and I will provide rules for that.

Option 1: Have both var name and var value in your URL like this:

www.example.com/page/var1/cat/var2/subcat/var3/subsubcat/var4 OR
www.example.com/othervar1/var1/othervar2/var2/othervar3/var3/othervar4/var4

This one gives you maximum flexibility and is very easy to handle in Rewrite rules if you are willing to go to this route. For this option Rewrite rules will need to be written only once and you will be fine for future changes as long # of variables don't change

Option 2: Have a difference start for each scheme. For ex:

www.example.com/handler1/var1/var2/var3/var4 OR
www.example.com/handler2/var1/var2/var3/var4

This one is gives you shorter URL but doesn't provide flexibility like previous option. But this one is also very easy to handle in Rewrite rules. However for this option Rewrite rules will need to be written for every combination

So I would recommend option 1 and would be happy to prepare a .htaccess for you if you like this option too.

.htaccess file for option 2

Options +FollowSymlinks -MultiViews
RewriteEngine on

# 404 handler
ErrorDocument 404 /notFound.php

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^handler1/([^/]+)/?$ /?page=$1 [NC,QSA,L]
RewriteRule ^handler1/([^/]+)/([^/]+)/?$ /?page=$1&cat=$2 [NC,QSA,L]
RewriteRule ^handler1/([^/]+)/([^/]*)/([^/]*)/?$ /?page=$1&cat=$2&subcat=$3 [NC,QSA,L]
RewriteRule ^handler1/([^/]+)/([^/]*)/([^/]*)/([^/]*)/?$ /?page=$1&cat=$2&subcat=$3subsubcat=$4 [NC,QSA,L]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^handler2/([^/]+)/?$ /?othervar1=$1 [NC,QSA,L]
RewriteRule ^handler2/([^/]+)/([^/]+)/?$ /?othervar1=$1&othervar2=$2 [NC,QSA,L]
RewriteRule ^handler2/([^/]+)/([^/]*)/([^/]*)/?$ /?othervar1=$1&othervar2=$2&othervar3=$3 [NC,QSA,L]
RewriteRule ^handler2/([^/]+)/([^/]*)/([^/]*)/([^/]*)/?$ /?othervar1=$1&othervar2=$2&othervar3=$3othervar4=$4 [NC,QSA,L]


.htaccess file for option 1

Options +FollowSymlinks -MultiViews
RewriteEngine on

# 404 handler
ErrorDocument 404 /notFound.php

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)(/.*)?$ $3?$1=$2 [N,QSA,DPI]
RewriteRule ^(/[^/]+|[^/]+/|/?)$ /index.php [L,QSA,DPI]

Using these rules a URL of http://localhost/n1/v1/n2/v2/n3/v3/n4/v4 will be INTERNALLY redirected to http://localhost/?n4=v4&n3=v3&n2=v2&n1=v1 treating each pair of URL segments separated by / as a name-value pair for QUERY_STRING. BUT keep in mind if URI doesn't have even number of segments eg: http://localhost/n1/v1/n2/ then it will be redirected to http://localhost/?n1=v1, discarding extra n2.



来源:https://stackoverflow.com/questions/5776208/mod-rewrite-for-url-variables-removing-empty-parameters-and-using-more-than-1fi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!