用PHP特性trait实现简易Laravel Facade

2022-05-15 0 960

下面由Laravel教程栏目给大家介绍如何利用PHP trait实现简易Facade,希望对大家有所帮助!

简述

Facade 可以有效帮我实现方法的静态化。Laravel 大部分的扩展包都使用了 Facade。【推荐:laravel视频教程】
下面的简易 Facade 主要是利用 PHP 的特性 trait,魔术方法 __callStatic,反射类 ReflectionClass

使用场景

后台系统大部分都会有类似这样的操作:

<?php$user = User::find($id);if (!$user) {    throw new \\Expection("资源不存在");}

这样似乎没有什么问题,但是还会存在下面这样的:

$article = Article::find($id);if (!$article) {    throw new \\Expection("资源不存在");}$article->delete();

这样写法十分不优雅。

上代码

1、首先我们应该要有一个 Service

<?phpnamespace App\\Services;use App\\Traits\\ModeServiceTrait;class ModelService extends BaseService{    use ModeServiceTrait;}

2、新建一个 Trait

trait 为了多继承而存在的,可以去 PHP官网 看文档。

<?phpnamespace App\\Traits;use \\ReflectionClass;use \\Exception;use \\ReflectionException;use Illuminate\\Database\\Eloquent\\Model;use App\\Exceptions\\ResourceException;/** * @method static Model find(string $className, int $id, callable $callback = null) * * @see Model * @package App\\Services */trait ModeServiceTrait{    /**     * 回调方法     *     * @param Model|null $model     * @param string $method     * @return Model     * @throws ResourceException     */    public static function callback(Model|null $model, string $method): Model    {        switch ($method)        {            case 'first':            case 'find':                if (!$model) {                    throw new ResourceException("资源不存在");                }                break;            default:                break;        }        return $model;    }    /**     * 调用不存在的方法时触发     *     * @param $method     * @param $args     * @return false|mixed     * @throws ReflectionException     * @throws ResourceException     * @throws Exception     */    public static function __callStatic($method, $args)    {        $className = $args[0];        $arg = $args[1];        // 判断模型类是否存在        if (!class_exists($className)) {            throw new Exception("The class {$className} could not be found. from:" . __CLASS__);        }        // 利用反射实例化其类        $reflection = new ReflectionClass($className);        $instance = $reflection->newInstanceArgs();        // 调用该不存在的方法        $model = call_user_func_array([$instance, $method], [$arg]);        // 如果存在复杂操作交给 callback        return isset($args[2]) ? $args[2]($model) : self::callback($model, $method);    }}

首先我们关注 __callStatic 这个魔术方法。 当调用不存在的静态方法时会触发该方法。和他相似的魔术方法是 __call。这是使用 __callStatic 是为了达到 Facade 的效果。

__callStatic 有两个回调参数 $method被调用的且不存在的方法$args$method 方法中所传递的参数(数组形式)。

这样一个简易的 trait 就完成了。

使用

我们新建一个 command

$ php artisan make:command TestCommand

写入下面的内容

<?phpnamespace App\\Console\\Commands;use Illuminate\\Console\\Command;use App\\Services\\ModelService;use App\\Models\\Article\\Article;class TestCommand extends Command{    /**     * The name and signature of the console command.     *     * @var string     */    protected $signature = 'test:test';    /**     * The console command description.     *     * @var string     */    protected $description = 'a test';    /**     * Create a new command instance.     *     * @return void     */    public function __construct()    {        parent::__construct();    }    /**     * Execute the console command.     */    public function handle()    {        $article = ModelService::find(Article::class, 1);        $article = ModelService::find(Article::class, 1, function ($model) {            return $model->load('author');        });    }}

其中的 Article 模型需要自己去创建。
接下来就可以看看效果了:

$ php artisan test:test

结语

这样我们就抛弃了使用 abstract 抽象类,来达到了跟 Facade 一样的效果。同时也做到了代码复用。
这样使用程序会多走很多步,但是跟优雅比起来,性能什么的都无所谓了。

表达不是很清楚,需要自己深入体会了。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

【声明:根据2013年1月30日《计算机软件保护条例》2次修订第17条规定: 为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存 储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬! 鉴于此,也希望大家按此说明研究软件!】
本站所有源码尽量保证原汁原味,如有特殊情况会作出声明及标注,网站资源不做任何二次加密(原版加密除外,不影响程序使用的不会做解密处理),方便您更好的学习参考。 在您的能力范围内,为了大环境的良性发展,请尽可能的选择正版资源。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

即刻码站__国内靠谱的站长资源下载平台 php教程 用PHP特性trait实现简易Laravel Facade https://www.jike1995.com/36680.html

常见问题
  • 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用
查看详情
  • 最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度
查看详情

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务