Laravel Reponse响应客户端示例详解(6)

/** * Call the terminate method on any terminable middleware. * * @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Response $response * @return void */ public function terminate($request, $response) { // 调用实现了terminate方法的中间件 $this->terminateMiddleware($request, $response); // 执行注册的callback $this->app->terminate(); }

laravel将控制器(闭包)返回的数据封装成response对象

public static function toResponse($request, $response) { if ($response instanceof Responsable) { $response = $response->toResponse($request); } if ($response instanceof PsrResponseInterface) { $response = (new HttpFoundationFactory)->createResponse($response); } elseif ($response instanceof Model && $response->wasRecentlyCreated) { $response = new JsonResponse($response, 201); } elseif (! $response instanceof SymfonyResponse && ($response instanceof Arrayable || $response instanceof Jsonable || $response instanceof ArrayObject || $response instanceof JsonSerializable || is_array($response))) { $response = new JsonResponse($response); } elseif (! $response instanceof SymfonyResponse) { $response = new Response($response); } if ($response->getStatusCode() === Response::HTTP_NOT_MODIFIED) { $response->setNotModified(); } return $response->prepare($request); }

观察上面的代码发现:

1 上面代码的作用是将路由节点返回的数据封装成Response对象等待发送

2 并且上面的代码存在大量的instanceof判断 (为什么要这样呢 是因为一旦我们从控制器中返回一个实现了

laravel指定接口的实例,laravel就知道该如何渲染这些响应给客户端 此时你可能还不清楚,请看下面的例子)

3 而且没有else分支(这是因为laravel允许我们直接返回reponse对象,当我们直接返回Resposne实例的时候会直接走到方法的最后一句话)

4 并且最终都调用的都是Symfony Response的prepare方法

我们先来看Responsable接口 在laravel中任何一个实现了此接口的对象 都可以响应给客户端

<?php namespace Illuminate\Contracts\Support; interface Responsable { /** * Create an HTTP response that represents the object. * * @param \Illuminate\Http\Request $request * @return \Symfony\Component\HttpFoundation\Response */ // 接收$request参数 // 返回Response对象 public function toResponse($request); } // 下面我们在控制器中返回一个实现此接口的实例 // 要实现的逻辑: 接收一个订单id 根据订单状态生成不同的响应,返回给客户端 1 定义路由 Route::get('yylh/{order}', "\App\Http\Controllers\Debug\TestController@checkStatus"); 2 创建响应 namespace App\Responses; use App\Models\Order; use Illuminate\Contracts\Support\Responsable; use Illuminate\Http\JsonResponse; class OrderStatusRes implements Responsable { protected $status; public function __construct(Order $order) { $this->status = $order->status; } public function toResponse($request) { if ($this->status) { // 订单以完成 return new JsonResponse('order completed', 200); } // 订单未结算 return view('needToCharge'); } } 3 创建控制器 <?php namespace App\Http\Controllers\Debug; use App\Http\Controllers\Controller; use App\Models\Order; use App\Responses\OrderStatusRes; class TestController extends Controller { public function checkStatus(Order $order) { return new OrderStatusRes($order); } } // 进行访问测试 // // // 可以看到丧心病狂的我们 通过控制器中的一行代码 就实现了根据订单的不同状态回复了不同的响应 // 我想说什么你们应该已经知道了

看toResponse代码 我们发现 只要我们想办法返回符合laravel规定的数据,最终都会被转换成laravel response实例 比如我们可以返回Responsable实例,Arrayable实例,Jsonable实例等等,大家可以尝试直接返回return new Response(),Response::create等等

Route::get('rawReponse', function () {

​ return new Response(range(1,10));

});

更多请查看这位老哥的博客

通过十篇水文,分享了从类的自动加载,到走完laravel的生命周期。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/031c11b01a1a2900bf9716186b4e5059.html