PHP path_info,Thinkphp controller not exists index\php

简介: 研究过thinkphp框架源码的,或者深入了解过mvc的,都应该知道thinkphp框架的路由,是根据path_info值来解析的,甚至传参也可以带在path_info中

写在前面


为什么写下这篇文章,嗯,因为又踩坑了。 问题背景:


  • php7.2
  • nginx
  • thinkphp5


问题体现: url如果以/为结尾 比如index.php/admin/,不会自动访问默认控制器、方法index,而是报错


controller not exists:app\admin\controller\index\Php


求知之路


研究过thinkphp框架源码的,或者深入了解过mvc的,都应该知道thinkphp框架的路由,是根据path_info值来解析的,甚至传参也可以带在path_info中


排查path_info的值


一路追踪源码,在thinkphp\library\think\Request.php 路径中,找到以下代码


/**
 * 673行左右
 *
 *
 * 获取当前请求URL的pathinfo信息(含URL后缀)
 * @access public
 * @return string
 */
public function pathinfo()
{
    if (is_null($this->pathinfo)) {
        if (isset($_GET[$this->config['var_pathinfo']])) {
            // 判断URL里面是否有兼容模式参数
            $pathinfo = $_GET[$this->config['var_pathinfo']];
            unset($_GET[$this->config['var_pathinfo']]);
            unset($this->get[$this->config['var_pathinfo']]);
        } elseif ($this->isCli()) {
            // CLI模式下 index.php module/controller/action/params/...
            $pathinfo = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : '';
        } elseif ('cli-server' == PHP_SAPI) {
            $pathinfo = strpos($this->server('REQUEST_URI'), '?') ? strstr($this->server('REQUEST_URI'), '?', true) : $this->server('REQUEST_URI');
        } elseif ($this->server('PATH_INFO')) {
            $pathinfo = $this->server('PATH_INFO');
        }
        // 分析PATHINFO信息
        if (!isset($pathinfo)) {
            foreach ($this->config['pathinfo_fetch'] as $type) {
                if ($this->server($type)) {
                    $pathinfo = (0 === strpos($this->server($type), $this->server('SCRIPT_NAME'))) ?
                    substr($this->server($type), strlen($this->server('SCRIPT_NAME'))) : $this->server($type);
                    break;
                }
            }
        }
        if (!empty($pathinfo)) {
            unset($this->get[$pathinfo], $this->request[$pathinfo]);
        }
        $this->pathinfo = empty($pathinfo)  '/' == $pathinfo ? '' : ltrim($pathinfo, '/');
    }
    return $this->pathinfo;
}


我尝试在这个方法里(目前来看,这里是分析path_info的第一门关)打印$_SERVER['PATH_INFO'] 打印出来的值大概为admin/index.php 然后在后续解析中,又会把.替换成/ 也就是admin/index/php 对应我们报错的app\admin\controller\index\Php


分析path_info来源


我们知道,$_SERVER超全局变量是在php中自动维护的,所以它的来源肯定来自以下两个方面之一


  • php底层
  • web服务器


经过找一些资料,我得知了该变量的值是来自web服务器,也就是我使用的nginx 宝塔安装的nginx,会自动维护很多常用配置,比如不同版本的php配置、path_info配置等等(有些自己编译安装的php没有path_info 需要自己添加) 在/www/server/nginx/conf 下有多个php版本的配置文件,在其中有一个配置项


fastcgi_index index.php;


fastcgi是什么意思大家可以先自行补充 ^ _ ^ 也就是该配置项影响了我们的运行 它的定义可以简单理解为:


默认值:none
使用字段:http, server, location
如果URI以斜线结尾,文件名将追加到URI后面,这个值将存储在变量$fastcgi_script_name中


测试: 把index.php改为index2.php 访问程序,报错变为:controller not exists:app\admin\controller\index2\Php 可以证实是该配置影响结果


总结处理


Web服务器该配置影响了程序运行,那么我们如何解决该问题


  • ① 修改thinkphp底层,把path_info最后的index.php替换掉
  • ② 修改web服务器该配置为none 去除
  • ③ 修改程序,遵循规范


基于业务迁移、兼容不同环境考虑,我选择第三种方案。也就是修改程序,不允许跳转或者访问带/结尾。

目录
相关文章
|
11天前
|
消息中间件 NoSQL Go
PHP转Go系列 | ThinkPHP与Gin框架之Redis延时消息队列技术实践
【9月更文挑战第7天】在从 PHP 的 ThinkPHP 框架迁移到 Go 的 Gin 框架时,涉及 Redis 延时消息队列的技术实践主要包括:理解延时消息队列概念,其能在特定时间处理消息,适用于定时任务等场景;在 ThinkPHP 中使用 Redis 实现延时队列;在 Gin 中结合 Go 的 Redis 客户端库实现类似功能;Go 具有更高性能和简洁性,适合处理大量消息。迁移过程中需考虑业务需求及系统稳定性。
|
1月前
|
前端开发 网络安全 PHP
PHP代码审计之MVC与ThinkPHP简介
PHP代码审计之MVC与ThinkPHP简介
29 2
|
1月前
|
PHP
PHP——安装ThinkPHP框架报错
PHP——安装ThinkPHP框架报错
17 0
|
2月前
|
Java API PHP
【亲测有效,官方提供】php版本企查查api接口请求示例代码,php请求企查查api接口,thinkphp请求企查查api接口
【亲测有效,官方提供】php版本企查查api接口请求示例代码,php请求企查查api接口,thinkphp请求企查查api接口
87 1
|
2月前
|
安全 前端开发 API
PHP框架详解 - ThinkPHP框架
PHP框架详解 - ThinkPHP框架
|
4月前
|
设计模式 前端开发 PHP
【PHP开发专栏】ThinkPHP框架实战开发
【4月更文挑战第29天】ThinkPHP是中国流行的PHP框架,以其轻量级、模块化和高安全性受到开发者欢迎。本文介绍了ThinkPHP的基础,包括MVC设计模式,以及核心组件如路由、数据库操作、表单处理、模板引擎和错误处理。通过一个博客系统示例,展示了如何进行项目开发,包括控制器、模型和视图的创建。使用ThinkPHP能有效提升开发效率,帮助开发者快速构建复杂的Web应用。
67 0
|
关系型数据库 MySQL PHP
PHP注册、登陆、6套主页-带Thinkphp目录解析-【白嫖项目】
PHP注册、登陆、6套主页-带Thinkphp目录解析-【白嫖项目】 CSDN 转过来的,所以格式与内容有些许错误请见谅
|
PHP
php模版引擎smarty出现Undefined index的解决方案
php模版引擎smarty出现Undefined index的解决方案
95 0
|
JSON 安全 PHP
【代码审计-PHP】基于Thinkphp框架开发的
【代码审计-PHP】基于Thinkphp框架开发的
169 0
【代码审计-PHP】基于Thinkphp框架开发的
|
PHP 数据库
PHP异常处理函数,Thinkphp调试
在thinkphp中,除了异常类携带的简单file、code、message、trace等 还会获取当前服务器的配置、脚本的参数(get/post…)、数据库查询语句等 然后组合成一个有排版、数据充足的页面展示给我们,方便了我们排查问题。
116 0
PHP异常处理函数,Thinkphp调试