什么是PATHINFO?

字面意思,就是文件路径信息。举个例子,下面连接中黑色突出部分,即为PATHINFO。

http://localhost/index.php/Home/Index/index/a/1/b/2?c=3

注意:c=3并不是pathinfo的一部分,它是一个query参数。

PATHINFO指的是URL的路径实际上不存在的时候,apache或者Nginx等通过一定的手段将不存在的路径,都是实际不存在路径保存到环境变量$_SERVER['PATH_INFO']中。也可以将它转化为$_GET['s']参数,TP也可以识别。也就是说当你访问TP项目的时候,你实际上访问的只是入口文件index.php,不管你后面有多长的路径,都是实际不存在的,转换成PATHINFO或$_GET['s']了而已。

那么THINKPHP就是根据PATHINFO,从中提取出分组名,模块名 ,类名,方法名,将剩余的部分转换成为$_GET变量,比如TP从PATHINFO字符串中提取'Home'字段串,将其保持到$_GET['g']$_GET['m']='Index'$_GET['a']='index'
$_GET['b']=2。可以dump('$_GET')看看。

URL路由

URL路由--Url Router,指的是,在TP进行常规url解析之前,先检测路由,如果发现有路由规则匹配当前的PATHINFO,那么URL解析则交给路由处理。

路由规则是由多条 rule=>router 规则组成的数组。(规则 =>路由器)

路由处理过程大概如下:

  1. 遍历路由规则rule,与当前PATHINFO字符串进行匹配,如果合法,则从PATHINFO中取出所需要的字符串。
  2. 路由中每条规则对应一个router,router中指定对应的模块以及方法,模块和方法可以用第1步中匹配到的字符串进行动态替代。
  3. 将剩余的参数都解析并写入到$_GET中。

URL的4种访问方式(这是重点!!)

1.普通模式也称为重写模式
例如:http://域名/项目名/入口文件?m=模块名&a=方法名&键1=值1&键2=值2

2.PATHINFO 模式 --重点 在后面使用非常多,如果想传多个参数可以使用键1/值1/键2/值2方法。
例如:http://域名/项目名/入口文件/模块名/方法名/键1/值1/键2/值2

3.REWRITE重写模式,去掉入口文件便于SEO优化
例如:http://域名/项目名/模块名/方法名/键1/值1/键2/值2

4.兼容模式
例如:http://域名/项目名/入口文件?s=模块名/方法名/键1/值1/键2/值2

REWRITE模式开启方法

Apache下面,首先要输出一下phpinfo(),查找Loaded Modules下的mod_rewrite。如果没有找到,则去修改配置文件http.conf,找到mod_rewrite那一行,去除扩展前面的分号;
然后在入口文件所在目录下创建.htaccess文件,具体配置如下:

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>

IIS

<rewrite>
 <rules>
 <rule name="OrgPage" stopProcessing="true">
 <match url="^(.*)$" />
 <conditions logicalGrouping="MatchAll">
 <add input="{HTTP_HOST}" pattern="^(.*)$" />
 <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
 <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
 </conditions>
 <action type="Rewrite" url="index.php/{R:1}" />
 </rule>
 </rules>
 </rewrite>

nginx 低版本

location / { // …..省略部分代码
   if (!-e $request_filename) {
       rewrite  ^(.*)$  /index.php?s=$1  last;
       break;
   }
}

nginx 二级目录

location /youdomain/ {
    if (!-e $request_filename){
        rewrite  ^/youdomain/(.*)$  /youdomain/index.php?s=$1  last;
    }
}

图片防盗链

语法:valid_referers none | blocked | server_names | String ...;
none 检测Referer头域不存在的情况

blocked  检测Referer头域的值被防火墙或代理服务器删除或伪装的情况。这种情况下,该头域的值不是以https://http://开头

server_names 设置一个或多个URL,检测Referer头域的值是否是这些URL中某个。

实现盗链有两种方式,一种是根据请求资源的资源类型。一种是根据请求的目录。

根据请求资源的资源类型

server
{
    ...
    listen 80;
    server_name www.myweb.name;
    location ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip)$
    {
        ...
        valid_referers none blocked server_name *. myweb.name;
        if($invalid_referer){
            rewrite ^/ http://www.myweb.com/images/forbidden.png;
        }
    }
}

根据请求的目录

server
{
    ...
    listen 80;
    server_name www.myweb.name;
    location /file/
    {
        ...
        root /server/file/;
        valid_referers none blocked server_name *. myweb.name;
        if($invalid_referer){
            rewrite ^/ http://www.myweb.com/images/forbidden.png;
        }
    }
}