博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Laravel响应宏原理
阅读量:6227 次
发布时间:2019-06-21

本文共 3635 字,大约阅读时间需要 12 分钟。

使用场景

我们在使用laravel来写API时,经常需要返回一个json字符串或JsonResponse,通常我们的做法可能有两种。

1、在BaseController中定义一个返回Json响应de方法,然后继承该BaseController。如:

//BaseController.phppublic function json($data = null, $status = 200, $headers = [], $options = 0){    return new JsonResponse($data, $status, $headers, $options);}//YourController.phpclass YourController extends BaseController{    public function users(UserRepository $userRepository)    {        return $this->json($userRepository->allUser());    }}

然而这写法确实挺方便,然而当你在其他地方需要使用到Json响应时(如中间件验证失败时你想要返回一个Json响应)。你无法使用到$this->json(...)

2、直接在需要用到Json响应得地方使用return new JsonResponse或者使用Response Facade

但这种做法当需要修改Response响应时得全部改动,不可取。

Response 宏

Laravel提供了一个非常方便的响应宏来处理这一情况

首先,我们需要先注册一个响应宏,在任意一个ServiceProviderboot方法里(ResponseMacroServiceProvider ),使用Response Facade注册

Response::macro('success', function ($data = [], $message = 'success') {    return new JsonResponse([        'code' => 0,        'data' => $data,        'message' => $message    ], 200);});

接下来, 你可以再任何地方使用它response()

//UserController.phppublic function users(UserRepository $userRepository){    return response()->success($userRepository->all(), 'success');}

注意,你只能通过response()这个全局方法或是app('Illuminate\Routing\ResponseFactory')来使用它

response()->success();//OKapp('Illuminate\Routing\ResponseFactory')->success();//OK//Response FacadeResponse::success();//ok(new \Illuminate\Http\Response)->success();//Error

原理

我们在ServiceProvider里使用Response Facade来注册的success宏,我们先看看Response这个Facade的正真类是什么。

// Illuminate\Support\Facades.phpprotected static function getFacadeAccessor(){    return 'Illuminate\Contracts\Routing\ResponseFactory';}

Facade返回了一个ResponseFactory接口,那该接口的具体实列对象时什么呢。

//Illuminate\Routing\RoutingServiceProvider.php/** * Register the response factory implementation. * * @return void */protected function registerResponseFactory(){    $this->app->singleton('Illuminate\Contracts\Routing\ResponseFactory', function ($app) {        return new ResponseFactory($app['Illuminate\Contracts\View\Factory'], $app['redirect']);    });}

可以看到,该RoutingServiceProvider注册了一个Illuminate\Routing\ResponseFactory的实列给Response Facade

我们在Illuminate\Routing\ResponseFactory的源码中可以看到,它引用了一个Illuminate\Support\Traits\Macroable trait

namespace Illuminate\Routing;use Illuminate\Support\Traits\Macroable;class ResponseFactory implements FactoryContract{    use Macroable;}

Trait源码如下,看完源码就知道为什么调用response()就能正常访问success方法了。

trait Macroable{    protected static $macros = [];    public static function macro($name, callable $macro)    {        static::$macros[$name] = $macro;    }    public static function hasMacro($name)    {        return isset(static::$macros[$name]);    }    public static function __callStatic($method, $parameters)    {        if (! static::hasMacro($method)) {            throw new BadMethodCallException("Method {$method} does not exist.");        }        if (static::$macros[$method] instanceof Closure) {            return call_user_func_array(Closure::bind(static::$macros[$method], null, static::class), $parameters);        }        return call_user_func_array(static::$macros[$method], $parameters);    }    public function __call($method, $parameters)    {        if (! static::hasMacro($method)) {            throw new BadMethodCallException("Method {$method} does not exist.");        }        if (static::$macros[$method] instanceof Closure) {            return call_user_func_array(static::$macros[$method]->bindTo($this, static::class), $parameters);        }        return call_user_func_array(static::$macros[$method], $parameters);    }}

其实该trait Illuminate\Support\Traits\Macroable在很多地方都有使用,包括FileSystemDatabase-Builder


转载地址:http://zanna.baihongyu.com/

你可能感兴趣的文章
深入浅出Git教程(转载)
查看>>
[转载]MySQL5.6 PERFORMANCE_SCHEMA 说明
查看>>
max_allowed_packet引起同步报错处理
查看>>
006 复杂的数据类型&函数(方法)
查看>>
javascript:getElementsByName td name
查看>>
ASP.NET连接SQL、Access、Excel数据库(二)——连接实例
查看>>
FreeRTOS 特性简介
查看>>
Linux--前后端分离部署
查看>>
java阶段学习目标
查看>>
Azure IoT 技术研究系列2
查看>>
day24-3-2子类继承构造方法
查看>>
我们一起学习WCF 第五篇数据协定和消息协定
查看>>
Linux 与 Windows 文件互传(VMWare)
查看>>
Python学习笔记八 面向对象高级编程(一)
查看>>
Oracle内置函数
查看>>
UVA 1645 Count
查看>>
贪吃蛇程序
查看>>
poj 1419 Graph Coloring
查看>>
node的安装及其运用及相关配置
查看>>
第19篇 2016年计划
查看>>