今天小编给大家分享一下怎么用PHP特性trait实现简易Laravel Facade的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。
简述
Facade
可以有效帮我实现方法的静态化。Laravel
大部分的扩展包都使用了 Facade
。
下面的简易 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;trait ModeServiceTrait{ 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; } 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{ protected $signature = 'test:test'; protected $description = 'a test'; public function __construct() { parent::__construct(); } 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
以上就是“怎么用PHP特性trait实现简易Laravel Facade”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网行业资讯频道。