关于thinkphp5手动抛出Http异常时自定义404页面报错的问题

在使用HttpException手动抛出异常时,希望跳转到自定义的错误页面,官方的文章中是这样描述的。

可以使用\think\exception\HttpException类来抛出异常

// 抛出 HTTP 异常  
throw new \think\exception\HttpException(404, '异常消息', null, [参数]);  

一旦抛出了HttpException异常,可以支持定义单独的异常页面的模板地址,只需要在应用配置文件中增加:

'http_exception_template'    =>  [  
    // 定义404错误的重定向页面地址  
    404 =>  APP_PATH.'404.html',  
    // 还可以定义其它的HTTP status  
    401 =>  APP_PATH.'401.html',  
]  

然而如果你这些都做完了,关闭调试模式,你会发现还是跳转到官方自定义的页面上去了,并且你发现http状态码是500,这是代码有问题啊,我抛出的是404啊。

然后打开log日志,你会发现果然报错了。

[ error ] [1]Uncaught think\exception\TemplateNotFoundException: template not exists:view/layout.html in /Applications/MAMP/htdocs/best.shiqidu.com/thinkphp/library/think/Template.php:1082  
Stack trace:  

这。。。
可怎么办。。。

只能看源码找问题了。

你会发现这个方法被调用了两次。

/**  
     * 解析模板文件名  
     * @access private  
     * @param  string $template 文件名  
     * @return string|false  
     */  
    private function parseTemplateFile($template)  
    {...}  

第一次时$template模板文件时能找到的。但是第二次也是一个相对路径view/layout,所以报错了,继续顺藤摸瓜,发现这个函数。

/**  
     * 编译模板文件内容  
     * @access private  
     * @param string    $content 模板内容  
     * @param string    $cacheFile 缓存文件名  
     * @return void  
     */  
    private function compiler(&$content, $cacheFile)  
    {  
        // 判断是否启用布局  
        if ($this->config['layout_on']) {  
            if (false !== strpos($content, '{__NOLAYOUT__}')) {  
                // 可以单独定义不使用布局  
                $content = str_replace('{__NOLAYOUT__}', '', $content);  
            } else {  
                // 读取布局模板  
                $layoutFile = $this->parseTemplateFile($this->config['layout_name']);  
                if ($layoutFile) {  
                    // 替换布局的主体内容  
                    $content = str_replace($this->config['layout_item'], $content, file_get_contents($layoutFile));  
                }  
            }  
        } else {  
            $content = str_replace('{__NOLAYOUT__}', '', $content);  
        }  
...  

 

关键就是这里了,如果你没有{__NOLAYOUT__}这个表示的话,它在渲染自定义404页面时会去加载布局文件(如果你在配置文件里开启了布局,如果没开启layout=true,也不会报这个错)。
而这个布局文件的路径是一个相对路径,这时如果你抛出异常的地方不是在applicationcontroller里,就找不到布局文件了。所以就报错了。

怎么解决呢?其实也很简单。给自定义的404页面加上{__NOLAYOUT__}就行了。

5d4af532dcaeab4d661a2932fcf09552.png

这一点官方文档没有说明,还在坑里的同学可以参考改下。

转载于:https://www.cnblogs.com/zmdComeOn/p/10647947.html

thinkphp6中,可以通过以下方式自定义抛出异常: 1. 创建自定义异常类 首先,我们需要创建一个自定义异常类,继承自think\Exception类,例如: ```php namespace app\exception; use think\Exception; class MyException extends Exception { protected $message = '自定义异常信息'; protected $code = 10001; } ``` 在上面的例子中,我们创建了一个名为MyException的自定义异常类,设置了异常信息和异常代码。 2. 抛出自定义异常 在需要抛出异常的地方,可以通过以下方式抛出自定义异常: ```php throw new MyException(); ``` 或者: ```php throw new MyException('自定义异常信息', 10001); ``` 在上面的例子中,我们使用了自定义异常类MyException,并传入了异常信息和异常代码。 3. 异常处理 最后,我们需要在异常处理的地方捕获并处理自定义异常,例如: ```php namespace app\exception; use think\exception\Handle; class ExceptionHandle extends Handle { public function render(\Exception $e) { if ($e instanceof MyException) { // 处理自定义异常 return json(['code' => $e->getCode(), 'msg' => $e->getMessage()]); } // 其他异常交给系统处理 return parent::render($e); } } ``` 在上面的例子中,我们创建了一个名为ExceptionHandle的异常处理类,继承自think\exception\Handle类,重写了render方法,在该方法中捕获并处理自定义异常MyException。 当系统抛出自定义异常,会调用ExceptionHandle的render方法进行处理,返回一个相应的响应结果。如果抛出异常不是自定义异常,则交给系统默认的异常处理方式处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值