Thinkphp nginx 下 404 问题排查及解决

更新日期: 2019-09-17 阅读次数: 14678 字数: 593 分类: thinkphp

从线上服务器拷贝下来一套 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_WRITE_ERROR:./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 聊聊, 查看更多联系方式