解决thinkphp自定义404页面无反应问题
孙泽辉 Lv5

最近在做php,发现添加了自定义404页面模板后没反应,仍然使用默认异常模板,查了一下源码才知道问题所在,都是自己惯性思维惹的祸。

文档说明:

异常处理 · ThinkPHP5.1完全开发手册 · 看云 (kancloud.cn)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// \thinkphp\helper.php
if (!function_exists('abort')) {
/**
* 抛出HTTP异常
* @param integer|Response $code 状态码 或者 Response对象实例
* @param string $message 错误信息
* @param array $header 参数
*/
function abort($code, $message = null, $header = [])
{
if ($code instanceof Response) {
throw new HttpResponseException($code);
} else {
throw new HttpException($code, $message, null, $header);
}
}
}

调用thinkphpabort函数可以方便地创建HTTP异常,从这里入手,看一下thinkphp是怎么处理http异常的。

这里通过$code区分了一下,相当于是实现了函数重载,$code参数是404,走HttpException

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

class HttpException extends \RuntimeException
{
private $statusCode;
private $headers;

public function __construct($statusCode, $message = null, \Exception $previous = null, array $headers = [], $code = 0)
{
$this->statusCode = $statusCode;
$this->headers = $headers;

parent::__construct($message, $code, $previous);
}
// ...
}

初始化之后,会自动被think\exception\Handle处理,调用内部render方法,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php
namespace think\exception;

class Handle
{
/**
* Render an exception into an HTTP response.
*
* @param \Exception $e
* @return Response
*/
public function render(Exception $e)
{
if ($this->render && $this->render instanceof \Closure) {
$result = call_user_func_array($this->render, [$e]);
if ($result) {
return $result;
}
}

if ($e instanceof HttpException) {
return $this->renderHttpException($e);
} else {
return $this->convertExceptionToResponse($e);
}
}

/**
* @param HttpException $e
* @return Response
*/
protected function renderHttpException(HttpException $e)
{
$status = $e->getStatusCode();
$template = Config::get('http_exception_template');
if (!App::$debug && !empty($template[$status])) {
return Response::create($template[$status], 'view', $status)->assign(['e' => $e]);
} else {
return $this->convertExceptionToResponse($e);
}
}

}

此时通过异常类型的判断,继续走renderHttpException,这个方法已经能够说明问题了,如果当前不是debug模式并且能够匹配到有对应模板,则会去找对应模板输出。显然我这里是走了else了,输出App::$debug值为'1',但是我明明设置了$debug=false。继续查看$debug来源,发现初始化$debug是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
class App
{
public static function initCommon()
{
// 初始化应用
$config = self::init();
self::$suffix = $config['class_suffix'];

// 应用调试模式
self::$debug = Env::get('app_debug', Config::get('app_debug'));
// ...
}
}

先读取env,再读取config.php,哦原来是我config.php写死之后,.env文件没有删掉。

thinkphp官方文档其实有写:

环境变量中设置的APP_DEBUGAPP_TRACE参数会自动生效(优先于应用的配置文件),其它参数则必须通过Env::get方法才能读取。

 Comments
Comment plugin failed to load
Loading comment plugin
Powered by Hexo & Theme Keep
Total words 87.1k