thinkPHP 自定义404页面 好用不贵

通过response的理解来创建一个404页面的控制器,来输出特定状态码的页面

##在这里尽情的书写你娴熟的markdown吧遇到这个问题好久了,一直没有什么好用方法,官方提供的配置解决不是很友好。于是,我开始了琢磨之路。

其实吧,这个也不怪原来几个月没有搞出来,这个东西只要自己认真深入的思考一下就可以得到答案。

我分析到

控制器方法里的渲染模板的方法是通过fetch()来实现的。跟踪进去,他使用的是 Response来向前端渲染模板以及数据的。

/**
     * 加载模板输出
     * @access protected
     * @param  string $template 模板文件名
     * @param  array  $vars     模板输出变量
     * @param  array  $config   模板参数
     * @return mixed
     */
    protected function fetch($template = '', $vars = [], $config = [])
    {
        return Response::create($template, 'view')->assign($vars)->config($config);
    }

发现他调用了Response的create方法。他这个Response::create()就是创建那个渲染模板的,后面的那个assign()是给前端模板传值的,我们的404页面不需要传值,也没有config,

我们再看一下Response里的各项方法

1、create() 方法干嘛的呢?

创建一个response对象,这个对象里有一个很扎眼的玩意叫code,我想这个code就应该是http状态码的code。

/**
     * 创建Response对象
     * @access public
     * @param  mixed  $data    输出数据
     * @param  string $type    输出类型
     * @param  int    $code
     * @param  array  $header
     * @param  array  $options 输出参数
     * @return Response
     */
    public static function create($data = '', $type = '', $code = 200, array $header = [], $options = [])
    {
        $class = false !== strpos($type, '\\') ? $type : '\\think\\response\\' . ucfirst(strtolower($type));

        if (class_exists($class)) {
            return new $class($data, $code, $header, $options);
        }

        return new static($data, $code, $header, $options);
    }

2、assign()干嘛的呢?

我不假思索的认为:这个是给模板传递数据的

3、config

这个目前我在整个项目里都还没有用到,具体应该也是传递一些特定的header参数,后面再展开研究一下。

答案

那么我们就可以模仿fetch方法来创建一个响应对象啊。来,事不宜迟,开干

/**
     * notFound : 通过response 创建 一个状态码为404的页面
     * @return Response
     */
    public function notFound(){
        //todo:: 这里修改这个控制器的状态码为404
        return Response::create($template='','view',404);
    }

现在我就得到了一个可以自己随意指定状态码的响应对象了,当然我们还可以把Response文件再阅读以下,里面都有哪些方法,例如:code()方法可以传递一个状态值来改变HTTP状态码等。

/**
     * 发送HTTP状态
     * @access public
     * @param  integer $code 状态码
     * @return $this
     */
    public function code($code)
    {
        $this->code = $code;

        return $this;
    }

那么我们也可以把上面的代码写成这样

/**
     * notFound : 通过response 创建 一个状态码为404的页面
     * @return Response
     */
    public function notFound(){
        //todo:: 这里修改这个控制器的状态码为404
        return Response::create($template='','view')->code(404);
    }

有了这个基础之后,我们怎样调用这个控制器呢?

1、首先要有个路由,可以去路由文件里添加进去

Route::get('/notfound','en_us/Base/notFound')->name('404');

2、在程序合适的地方调用redirect方法来获得自由

例如:

 try{
      if(!empty($data)){
            .
            .
            .
            } else {
                $this->redirect(url('404'),[],404);
            }
     }catch (Exception $exception){
            $this->redirect(url('500'),[],500);
     }

3、至于哪些地方合适,在于编程思路,例如我的这个一般会在service层处理,或者控制器层处理

上面的代码可能跟还有些问题,可以通过自己的理解然后再优化,例如,try cache 后面会遇到问题,我们可以在跳转前记录一下日志,方便查找bug。

Log::error($exception->getMessage());// 可以把这个方法名也传递进去,免得只有光秃秃的一个错误,不知道他触发的位置
Log::close();

总结

代码不是一次性就写完整的,我们需要把一个大东西分解成一些小小的零件,来拼凑它,最后我们就可以做成一个了不起的东西。

分析问题,先把问题的重要点分析出来,例如:我们这个问题点是向前端输出一个404页面

这个问题点可以分解为:

1、通过什么实现?

2、从哪个切入点入手?

3、完成初步模型

4、精细化修改

5、完成该问题

6、推广到相邻的问题点上去,例如我们本例的500服务器错误页面,403权限拒绝页面等遇到这个问题好久了,一直没有什么好用方法,官方提供的配置解决不是很友好。于是,我开始了琢磨之路。

其实吧,这个也不怪原来几个月没有搞出来,这个东西只要自己认真深入的思考一下就可以得到答案。

我分析到

控制器方法里的渲染模板的方法是通过fetch()来实现的。跟踪进去,他使用的是 Response来向前端渲染模板以及数据的。

/**
     * 加载模板输出
     * @access protected
     * @param  string $template 模板文件名
     * @param  array  $vars     模板输出变量
     * @param  array  $config   模板参数
     * @return mixed
     */
    protected function fetch($template = '', $vars = [], $config = [])
    {
        return Response::create($template, 'view')->assign($vars)->config($config);
    }

发现他调用了Response的create方法。他这个Response::create()就是创建那个渲染模板的,后面的那个assign()是给前端模板传值的,我们的404页面不需要传值,也没有config,

我们再看一下Response里的各项方法

1、create() 方法干嘛的呢?

创建一个response对象,这个对象里有一个很扎眼的玩意叫code,我想这个code就应该是http状态码的code。

/**
     * 创建Response对象
     * @access public
     * @param  mixed  $data    输出数据
     * @param  string $type    输出类型
     * @param  int    $code
     * @param  array  $header
     * @param  array  $options 输出参数
     * @return Response
     */
    public static function create($data = '', $type = '', $code = 200, array $header = [], $options = [])
    {
        $class = false !== strpos($type, '\\') ? $type : '\\think\\response\\' . ucfirst(strtolower($type));

        if (class_exists($class)) {
            return new $class($data, $code, $header, $options);
        }

        return new static($data, $code, $header, $options);
    }

2、assign()干嘛的呢?

我不假思索的认为:这个是给模板传递数据的

3、config

这个目前我在整个项目里都还没有用到,具体应该也是传递一些特定的header参数,后面再展开研究一下。

答案

那么我们就可以模仿fetch方法来创建一个响应对象啊。来,事不宜迟,开干

/**
     * notFound : 通过response 创建 一个状态码为404的页面
     * @return Response
     */
    public function notFound(){
        //todo:: 这里修改这个控制器的状态码为404
        return Response::create($template='','view',404);
    }

现在我就得到了一个可以自己随意指定状态码的响应对象了,当然我们还可以把Response文件再阅读以下,里面都有哪些方法,例如:code()方法可以传递一个状态值来改变HTTP状态码等。

/**
     * 发送HTTP状态
     * @access public
     * @param  integer $code 状态码
     * @return $this
     */
    public function code($code)
    {
        $this->code = $code;

        return $this;
    }

那么我们也可以把上面的代码写成这样

/**
     * notFound : 通过response 创建 一个状态码为404的页面
     * @return Response
     */
    public function notFound(){
        //todo:: 这里修改这个控制器的状态码为404
        return Response::create($template='','view')->code(404);
    }

有了这个基础之后,我们怎样调用这个控制器呢?

1、首先要有个路由,可以去路由文件里添加进去

Route::get('/notfound','en_us/Base/notFound')->name('404');

2、在程序合适的地方调用redirect方法来获得自由

例如:

 try{
      if(!empty($data)){
            .
            .
            .
            } else {
                $this->redirect(url('404'),[],404);
            }
     }catch (Exception $exception){
            $this->redirect(url('500'),[],500);
     }

3、至于哪些地方合适,在于编程思路,例如我的这个一般会在service层处理,或者控制器层处理

上面的代码可能跟还有些问题,可以通过自己的理解然后再优化,例如,try cache 后面会遇到问题,我们可以在跳转前记录一下日志,方便查找bug。

Log::error($exception->getMessage());// 可以把这个方法名也传递进去,免得只有光秃秃的一个错误,不知道他触发的位置
Log::close();

总结

代码不是一次性就写完整的,我们需要把一个大东西分解成一些小小的零件,来拼凑它,最后我们就可以做成一个了不起的东西。

分析问题,先把问题的重要点分析出来,例如:我们这个问题点是向前端输出一个404页面

这个问题点可以分解为:

1、通过什么实现?

2、从哪个切入点入手?

3、完成初步模型

4、精细化修改

5、完成该问题

6、推广到相邻的问题点上去,例如我们本例的500服务器错误页面,403权限拒绝页面等


参考文献

相关文章