Thinkphp nginx 下 404 问题排查及解决

文章目录

    从线上服务器拷贝下来一套 thinkphp 的网站代码,在本地欲搭建一套开发调试环境。但是按照之前 Laravel 的 nginx 配置之后,一直报 404。Nginx 错误日志中并没有任何的错误记录。

    系统环境

    • ubuntu 18.04
    • nginx 1.14.0
    • thinkphp 3.2.3

    排除 nginx 默认不支持 pathinfo 模式的问题

    网上很多人说是因为,nginx 默认不支持 pathinfo 模式所以会出现 404 的问题。

    确认 thinkphp 项目使用的模式:

    vim Web/Common/Conf/config.php 可以看到

    'URL_MODEL'  => 2,
    // 0 (普通模式); 1 (PATHINFO 模式); 2 (REWRITE  模式); 3 (兼容模式)  默认为PATHINFO 模式
    

    可见,这里使用的是 REWRITE 模式,所以不是 pathinfo 模式引起的问题。

    php.ini 禁用 pathinfo+

    sudo vim /etc/php/7.1/fpm/php.ini

    将 cgi.fix_pathinfo=1 改为 cgi.fix_pathinfo=0

    PATHINFO 模式与 REWRITE 模式的区别

    • pathinfo 模式:URL 类似 /index.php/home/user/verify
    • rewrite 模式: URL 类似 /?s=/home/user/verify

    对比线上生产环境的 Nginx 配置

    $ ps axuw | grep nginx
    nginx: master process /www/server/nginx/sbin/nginx -c /www/server/nginx/conf/nginx.conf
    

    检查了一遍,并没有任何特殊的配置。

    include proxy.conf;    
    include /www/server/panel/vhost/nginx/*.conf;
    

    纯 php 测试

    http://localhost/test.php

    <?php echo 'hello world'?>
    

    纯 php 文件时是执行正常的,只有 thinkphp 的 index.php 网页代码会出 404 问题。

    thinkphp index.php 文件排查

    在代码头部加入

    echo 'hello1111';
    

    页面也可以正常显示。

    接下来,具体具体看看到底是哪里出现了问题:

    require './ThinkPHP/ThinkPHP.php';
    

    这个文件有问题:

    Think\Think::start(); 
    

    这里报错 404。

    开启 thinkphp 3.2 的 debug 日志显示

    index.php

    define('APP_DEBUG',true);
    

    Web/Common/Conf/config.php

    'SHOW_PAGE_TRACE' =>true, //开启页面Trace功能
    'TMPL_EXCEPTION_FILE'    =>   APP_DEBUG ? THINK_PATH.'Tpl1/think_exception.tpl' : './Web/En/View/Public/404.html', //404设置
    

    注意要确保 TMPL_EXCEPTION_FILE 的模板文件存在。

    然后就能看到具体的错误原因了。

    具体的错误原因

    _STORAGE_WRITEERROR:./Web/Runtime/Cache/En/5fcb76d902092e0ce635cda9b350a6fc.php
    错误位置
    FILE: /ThinkPHP/Library/Think/Storage/Driver/File.class.php  LINE: 48

        /**
         * 文件写入
         * @access public
         * @param string $filename  文件名
         * @param string $content  文件内容
         * @return boolean         
         */
        public function put($filename,$content,$type=''){
            $dir         =  dirname($filename);
            if(!is_dir($dir)){
                mkdir($dir,0777,true);
            }
            if(false === file_put_contents($filename,$content)){
                E(L('_STORAGE_WRITE_ERROR_').':'.$filename);   // 第 48 行
            }else{
                $this->contents[$filename]=$content;
                return true;
            }
        }
    

    感觉是写文件的权限问题。

    echo $dir;

    ./Web/Runtime/Cache/En
    

    ls -la 之后,可以看到没有一个今天产生的文件,说明没有权限写入。

    开发环境设置 777 权限也没啥隐患,所以

    sudo chmod 777 -R ./Web/Runtime/Cache/
    

    网站果然可以正常显示了。

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式