关于PATHINFO的重写规则解析

本文探讨了PHP框架如Laravel、Yii、ThinkPHP等如何利用URL重定向实现PATH_INFO功能,通过解析$_SERVER['REQUEST_URI']变量获取原始URL路径,进而解析为控制器和方法名,简化了路径管理。

最近比较流行的框架比如laravel,yii国内的thinkphp都提供了以重定url的方式来实现pathinfo的url风格。

以thinkphp为例,提供了名为 "s"的get参数,只需要将路径重定向到这个参数上即可,比如nginx下:


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



根本不用费大力气写一大堆代码实现所谓的PATH_INFO.


现在laravel和yii2的重写规则更加简单,仅仅需要:


location / {
        
        try_files $uri $uri/ /index.php?$args;
}



apache类似的规则:



RewriteEngine on

# If a directory or a file exists, use the request directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Otherwise forward the request to index.php
RewriteRule . index.php



解释下规则:


当你访问一个无法访问的路径时,比如 localhost/Index/index 实际上在你的webroot目录是没有Index/index目录或Index/index.html文件的,这时候我们就需要让框架来处理请求,将/Index/index 这个路径交给框架,而框架唯一的入口就是localhost/index.php,所以我们只需要将该请求重写到这个url上就可以了。

当访问

localhost/index/index?a=1 

时,会重定向到:

localhost/index.php?a=1

那么/index/index这个字符串哪去了?答案应该在一个环境变量$_SERVER['REQUEST_URI']或者类似的变量,让我们通过Yii2里面的一个函数来研究一下具体流程:


protected function resolveRequestUri()
    {
        if (isset($_SERVER['HTTP_X_REWRITE_URL'])) { // IIS
            $requestUri = $_SERVER['HTTP_X_REWRITE_URL'];
        } elseif (isset($_SERVER['REQUEST_URI'])) {
            $requestUri = $_SERVER['REQUEST_URI'];
            if ($requestUri !== '' && $requestUri[0] !== '/') {
                $requestUri = preg_replace('/^(http|https):\/\/[^\/]+/i', '', $requestUri);
            }
        } elseif (isset($_SERVER['ORIG_PATH_INFO'])) { // IIS 5.0 CGI
            $requestUri = $_SERVER['ORIG_PATH_INFO'];
            if (!empty($_SERVER['QUERY_STRING'])) {
                $requestUri .= '?' . $_SERVER['QUERY_STRING'];
            }
        } else {
            throw new InvalidConfigException('Unable to determine the request URI.');
        }

        return $requestUri;
    }



这个方法应该是用获得重定向之前的url,也就是你浏览器地址栏中所显示的 /index/index?a=1 这个原始字符串。在nginx和apache中,默认的是$_SERVER['REQUEST_URI']而在iis中略有不同,比如$_SERVER['HTTP_X_REWRITE_URL']和$_SERVER['ORIG_PATH_INFO']。

好了,不管它处理过程,我们只要知道通过这个方法得到了原始url,然后我们可以根据这个url来解析pathinfo吧::

if (!empty($_SERVER['REQUEST_URI']))
    {
      $path = preg_replace('/\?.*$/sD', '', $_SERVER['REQUEST_URI']);
    }



$path得到了什么?就是 /index/index ,然后再去根据路由得到控制器名index和方法名index。


以上只是我个人的猜测,并未深入yii2框架追根溯源,如有错误请指出,不胜感激。


转载于:https://my.oschina.net/cxz001/blog/270551

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值