一条简单的路由
(以下内容都是我当时有限的理解,后面自己理解深入了再更新,有错误也希望能帮忙指正下)
在webserver环境里,我们经常要用到路由,将url重写解析,才能访问到真正的接口。
以Nginx为例,一个http请求(或者其他协议)通过网页或者端上发送到服务器上,这里的服务器只的是物理服务器,相当于电脑,电脑上装有Nginx服务器。
这里需要提的一点是,Nginx和Apache的侧重点不同,Apache侧重在完整稳定上,而Nginx侧重在轻量高效上,很多时候Apache和Nginx是配合使用的,Nginx配置在Apache前面,用它挡掉静态文件的请求(网站今天资源的请求占了大部分的),Nginx处理不了的内容菜才转发给Apache来处理。
这里我只拿单Nginx考虑。一个到了Nginx的url,通过反向代理访问到内网,会在webserver层被路由重写。(我的重写文件在~/webserver/conf/vhost/php.conf),在被处理后的uri会接着被框架下的重写规则重写,然后才能访问真正的接口/文件。
举其中最简单的一条重写规则。
rewrite ^/([^/.]*)(/[^\?]*)?((\?.*)?)$ /$1/index.php$2$3 break
这条规则的结果是 将 http://www.test.com/hi/word 重写为 http://www.test.com/hi/index.php/word,我们可以在webroot下的hi模块下找到index.php这个文件。
index.php的作用是实例化框架
现在,我们来解析下这一条规则究竟做了什么
php正则
先学习下PHP正则表达式的知识。
1. 定位符
定位符用于规定匹配模式在目标对象中出现位置。常用的有"^"、"$"、"\b"、“\B”
(1)“^”定位符规定匹配模式必须出现在目标字符串的开头
(2)“$”定位符规定匹配模式必须出现在目标对象的结尾
(3)\b定位符规定匹配模式必须出现在目标字符串的开头或结尾的两个边界之一
(4)“\B”定位符则规定匹配对象必须位于目标字符串的开头和结尾两个边界之内
这里就规定了上面例子的匹配位置
2.定界符
“/”是定界符,“/”定界符之间的部分就是将要在目标对象中进行匹配的模式。
(1)“+”元字符规定其前导字符必须在目标对象中连续出现一次或多次
比如:/php+/,能够与“phpp”匹配
(2)“*”元字符规定其前导字符必须在目标对象中出现零次或连续多次
比如:/php*/能够与“phpddt”相匹配
(3)“?”元字符规定其前导对象必须在目标对象中连续出现零次或一次。
比如:/php?/能够“phpr”匹配
惰性匹配(记住:会进行两部操作,请看下面的原理部分)
格式:限定符?
原理:”?”:如果前面有限定符,会使用最小的数据。如“*”会取0个,而“+”会取1个,如过是{3,5}会取3个。
3. 否定符
[^]规定目标对象中不能存在模式中规定的字符串
[^phpddt]匹配除了phpddt字符外的所有东西
总结
ok,结合一二三三点来看,([^/.]*)对应$1,(/[^\?]*)对应$2,[^/.]和[^\?]筛选了元字符和一些符号防止恶意访问。
“?“后面为如果存在url参数的处理,这个就留着大家自己思考吧!