Laravel 在构造函数中使用 abort 函数时

laravel 在构造函数中使用abort函数时,页面出现两次,应该如何正确的使用?

<?php
use Illuminate\Http\Request;

class IndexController extends Controller
{
    public function __construct(Request $request)
    {
        abort(503);
    }

    public function index()
    {
        # code...
    }
}       

503.blade.php

<div>503</div>

这个时候,页面显示两个503,该如何正确使用啊

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 2

很好奇这个问题,所以看了一下。

abort(503) 到底是干了什么?

abort(503) 这个辅助函数,其实只是调用了 Illuminate\Foundation\Application@abort 方法抛出一个异常

throw new HttpException($code, $message, null, $headers);

问题是如果写在方法里面是正常的,为什么写在构造函数里面就会有问题呢?

打开 public/index.php 在 $response->send(); 后面 dd(1) 看一下,到目前为止一切都正常,不管写在构造函数里面还是方法里面都只是输出了一个

503

,所以问题就出在下一句:$kernel->terminate($request, $response);.

这句的作用是干嘛?我们知道中间件有一个叫Terminable 中间件,也就是在响应之后处理的中间件,这个方法就是处理这个中间件的。

为什么处理中间件会导致再次发送一次

503

? 关键在控制器中间件

Illuminate\Foundation\Http\Kernel@terminate 会合并所有的路由中间件,包括控制器中间件。

而获取控制器中间件的时候就需要获取控制器。

Illuminate\Routing\Route@getController 方法原则上回缓存控制器:

public function getController()
    {
        list($class) = explode('@', $this->action['uses']);

        if (! $this->controller) {
            $this->controller = $this->container->make($class);
        }

        return $this->controller;
    }

但是,不知道是因为垃圾回收还是触发了事件,导致控制器没有缓存,所以又重新创建了控制器

我们可以var_dump 一下看看:

var_dump($this->controller);

结果:

NULL
503
NULL
503

这才是罪魁祸首,因为控制器没有被缓存,而处理 Terminable 中间件 时又重新创建了一个控制器,相当于又抛出了一个 HttpException ,而 ExceptionHandler 就重新发送了一个响应。

7年前 评论

很好奇这个问题,所以看了一下。

abort(503) 到底是干了什么?

abort(503) 这个辅助函数,其实只是调用了 Illuminate\Foundation\Application@abort 方法抛出一个异常

throw new HttpException($code, $message, null, $headers);

问题是如果写在方法里面是正常的,为什么写在构造函数里面就会有问题呢?

打开 public/index.php 在 $response->send(); 后面 dd(1) 看一下,到目前为止一切都正常,不管写在构造函数里面还是方法里面都只是输出了一个

503

,所以问题就出在下一句:$kernel->terminate($request, $response);.

这句的作用是干嘛?我们知道中间件有一个叫Terminable 中间件,也就是在响应之后处理的中间件,这个方法就是处理这个中间件的。

为什么处理中间件会导致再次发送一次

503

? 关键在控制器中间件

Illuminate\Foundation\Http\Kernel@terminate 会合并所有的路由中间件,包括控制器中间件。

而获取控制器中间件的时候就需要获取控制器。

Illuminate\Routing\Route@getController 方法原则上回缓存控制器:

public function getController()
    {
        list($class) = explode('@', $this->action['uses']);

        if (! $this->controller) {
            $this->controller = $this->container->make($class);
        }

        return $this->controller;
    }

但是,不知道是因为垃圾回收还是触发了事件,导致控制器没有缓存,所以又重新创建了控制器

我们可以var_dump 一下看看:

var_dump($this->controller);

结果:

NULL
503
NULL
503

这才是罪魁祸首,因为控制器没有被缓存,而处理 Terminable 中间件 时又重新创建了一个控制器,相当于又抛出了一个 HttpException ,而 ExceptionHandler 就重新发送了一个响应。

7年前 评论

囧,刚刚又看了下为什么控制器没有缓存,根本不是垃圾回收或触发什么事件,而是压根就没有创建控制器,控制器创建的时候调用 abort(503) 就抛出异常了。。。。

搞不懂为什么要这样用~~

7年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!