用PHP特性trait实现简易Laravel Facade
3422
下面给大家介绍如何利用PHP trait实现简易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
- <?php
- namespace App\Services;
- use App\Traits\ModeServiceTrait;
- class ModelService extends BaseService
- {
- use ModeServiceTrait;
- }
2、新建一个 Trait
trait 为了多继承而存在的,可以去 PHP官网 看文档。
- <?php
- namespace 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
写入下面的内容
- <?php
- namespace 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
一样的效果。同时也做到了代码复用。
这样使用程序会多走很多步,但是跟优雅比起来,性能什么的都无所谓了。
表达不是很清楚,需要自己深入体会了。
本文网址:https://www.zztuku.com/detail-10870.html
站长图库 - 用PHP特性trait实现简易Laravel Facade
申明:本文转载于《learnku》,如有侵犯,请 联系我们 删除。
您还没有登录,请 登录 后发表评论!
提示:请勿发布广告垃圾评论,否则封号处理!!