The following tutorial column from Laravel will introduce how to use PHP traits to implement a simple Facade. I hope it will be helpful to everyone!
##Brief Description
Facade can effectively help me realize the staticization of the method.
Laravel Most extension packages use
Facade. [Recommended:
laravel video tutorial]The following simple
Facade mainly uses PHP's features
trait, magic method
__callStatic, Reflection Class
ReflectionClass.
Usage scenarios
Most background systems will have operations similar to this:<?php $user = User::find($id);if (!$user) { throw new \Expection("资源不存在");}
$article = Article::find($id);if (!$article) { throw new \Expection("资源不存在");}$article->delete();
Code
1. First we should have a Service
<?phpnamespace App\Services;use App\Traits\ModeServiceTrait;class ModelService extends BaseService{ use ModeServiceTrait;}
2. Create a new Trait
trait exists for multiple inheritance. You can go to the PHP official website to read the documentation.<?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 magic method. This method is triggered when a non-existing static method is called. A magic method similar to his is
__call. This is to use
__callStatic to achieve the effect of
Facade.
__callStatic There are two callback parameters
$method is a
called method that does not exist ,
$args It is the parameter (array form) passed in the
$method method.
trait is completed.
Use
We create a newcommand
$ 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 model needs to be created by yourself.
Next you can see the effect:
$ php artisan test:test
Conclusion
In this way we abandon the use ofabstract Abstract class to achieve the same effect as
Facade. Code reuse is also achieved.
Using the program in this way will take a lot more steps, but compared to elegance, performance doesn't matter.
The above is the detailed content of Implementing a simple Laravel Facade using PHP features traits. For more information, please follow other related articles on the PHP Chinese website!