开发者

How to KISS with RewriteRule (Apache)

I'm writing a little web app and I need to do some rewrite rules as I'm lazy and don't want to do it in PHP. And I see myself writing a LOT of rules for maybe nothing so I seek your advices and help !

Note :

- YEAR is 4 digits
- MONTH is two digits
- DAY is two digits
- TITLE is a long word including -, like : i-am-a-title
- NB_PAGE is only number (no limit here)
- The trailing slash is not mandatory

I need to satisfy this scheme :

1. /YEAR/MONTH/DAY/title => index.php?title=TITLE
2. /page/NB_PAGE => index.php?page=NB_PAGE

3. /YEAR/MONTH/DAY/ => index.php?year=YEAR&month=MONTH&day=DAY
4. /YEAR/MONTH/DAY/page/NB_PAGE => index.php?year=YEAR&month=MONTH&day=DAY&page=NB_PAGE

5. /YEAR/MONTH/ => 开发者_如何学Goindex.php?year=YEAR&month=MONTH
6. /YEAR/MONTH/page/NB_PAGE => index.php?year=YEAR&month=MONTH&page=NB_PAGE

7. /YEAR/ => index.php?year=YEAR
8. /YEAR/page/NB_PAGE => index.php?year=YEAR&page=NB_PAGE

9. /archives/ => _cache/archive.html
10. /feed/ => /_atom.xml

11. Everything NOT starting with a _ is considered a title and will redir to index.php?title=TITLE

Also:

  1. it must not block existing folder : (this part can be easily scripted to add a rewrite rules for each folder at the root of the app.)

    • If there is a directory called image and I browse using http://host/image/test.png I shall access to image and I should not get /image/test.png in the $_GET['title'] variable
  2. it must not block real files, if I want http://host/file-that-exists.txt, I should have it. See the comment below if the file is in a directory.

Actually I came with this :

<IfModule mod_rewrite.c>
RewriteEngine On

RewriteRule ^(.*).php(/?$) $1.php [L,QSA]
RewriteRule ^([0-9]{4})/([0-9]{2})/([0-9]{2})/(\w*\b)(/?$) index.php?title=$4 [L,QSA]
RewriteRule ^([0-9]{4})/([0-9]{2})/([0-9]{2})(/?$) index.php?year=$1&month=$2&day=$3 [L,QSA]
RewriteRule ^([0-9]{4})/([0-9]{2})/([0-9]{2})/page/([0-9]+)(/?$) index.php?year=$1&month=$2&day=$3&page=$4 [L,QSA]
RewriteRule ^([0-9]{4})/([0-9]{2})(/?$) index.php?year=$1&month=$2 [L,QSA]
RewriteRule ^([0-9]{4})/([0-9]{2})/page/([0-9]+)(/?$) index.php?year=$1&month=$2&page=$3 [L,QSA]
RewriteRule ^([0-9]{4})(/?$) index.php?year=$1 [L,QSA]
RewriteRule ^([0-9]{4})/page/([0-9]+)(/?$) index.php?year=$1&page=$2 [L,QSA]
RewriteRule ^(archives\b)(/?$) _cache/archive.html [L,QSA]
RewriteRule ^(feed\b)(/?$) /_atom.xml [L,QSA]
RewriteRule ^page/([0-9]+)(/?$) index.php?page=$1 [L,QSA]
RewriteRule ^([^_/].*)(/?$) index.php?title=$1 [L,QSA]
</IfModule>

But it's not working for the /image/ example and I'm feeling I'm going on a bad path with this... I repeat, I don't want to handle this in PHP. I really do think rewriterule are more flexible for me here.

Thank you very much for your help and guidance.

Hope my english is any good as it is not my native language.


to redirect if file/folder doesnt exist: .htaccess redirect if file doesn't exist

(you can combine that with your rewriterule (no _)


fix

apparently mod_rewrite doesnt handle group names and non capturing groups

until u accept some answer here is a demo (will edit this out later) : http://zaliczam.pl/test/2000/13/75/page/1

http://zaliczam.pl/test/0000/00/00/page/0/?like=a%20g6

RewriteEngine On

RewriteRule ^([0-9]{4})(/([0-9]{2})(/([0-9]{2}))?)?(/page/([0-9]+))?/?\s*$ index.php?year=$1&month=$3&day=$5&page=$7 [L,QSA]

why not catch all those in one

^(?<year>[0-9]{4})(/(?<month>[0-9]{2})(/(?<day>[0-9]{2}))?)?(/page/(?<page>[0-9]+))?/?\s*$

index.php?year=$year&month=$month&day=$day&page=$page

this matches

RewriteRule ^([0-9]{4})/([0-9]{2})/([0-9]{2})/(\w*\b)(/?$) index.php?title=$4 [L,QSA]
RewriteRule ^([0-9]{4})/([0-9]{2})/([0-9]{2})(/?$) index.php?year=$1&month=$2&day=$3 [L,QSA]
RewriteRule ^([0-9]{4})/([0-9]{2})/([0-9]{2})/page/([0-9]+)(/?$) index.php?year=$1&month=$2&day=$3&page=$4 [L,QSA]
RewriteRule ^([0-9]{4})/([0-9]{2})(/?$) index.php?year=$1&month=$2 [L,QSA]
RewriteRule ^([0-9]{4})/([0-9]{2})/page/([0-9]+)(/?$) index.php?year=$1&month=$2&page=$3 [L,QSA]
RewriteRule ^([0-9]{4})(/?$) index.php?year=$1 [L,QSA]
RewriteRule ^([0-9]{4})/page/([0-9]+)(/?$) index.php?year=$1&page=$2 [L,QSA]


if you can cope with title's without . then I would suggest changing the last line:

RewriteRule ^([^_/][^\.]*)(/?$) index.php?title=$1 [L,QSA]

Edit: the last rule matches almost everything without "_" to start with, so you need to give some regular exp match that it would understand its a file.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜