新西兰服务器

怎么用PHP特性trait实现简易Laravel Facade


怎么用PHP特性trait实现简易Laravel Facade

发布时间:2022-01-28 18:54:00 来源:高防服务器网 阅读:85 作者:iii 栏目:编程语言

今天小编给大家分享一下怎么用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 AppServices;use AppTraitsModeServiceTrait;class ModelService extends BaseService{      use ModeServiceTrait;}

2、新建一个 Trait

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

<?php  namespace AppTraits;  use ReflectionClass;  use Exception;use ReflectionException;  use IlluminateDatabaseEloquentModel;  use AppExceptionsResourceException;  /**   * @method static Model find(string $className, int $id, callable $callback = null)   *   * @see Model   * @package AppServices   */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 AppConsoleCommands;  use IlluminateConsoleCommand;  use AppServicesModelService;  use AppModelsArticleArticle;  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

以上就是“怎么用PHP特性trait实现简易Laravel Facade”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注高防服务器网行业资讯频道。

[微信提示:高防服务器能助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。

[图文来源于网络,不代表本站立场,如有侵权,请联系高防服务器网删除]
[