Home  >  Article  >  PHP Framework  >  Implementing a simple Laravel Facade using PHP features traits

Implementing a simple Laravel Facade using PHP features traits

藏色散人
藏色散人forward
2022-01-27 16:33:012080browse

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 ClassReflectionClass.

Usage scenarios

Most background systems will have operations similar to this:

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

There seems to be no problem, But there will also be the following:

$article = Article::find($id);if (!$article) {
    throw new \Expection("资源不存在");}$article->delete();
This way of writing is very inelegant.

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 &#39;first&#39;:
            case &#39;find&#39;:
                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);
    }}
First we focus on the

__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.

Such a simple

trait is completed.

Use

We create a new

command

$ php artisan make:command TestCommand
Write the following content

<?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 = &#39;test:test&#39;;

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = &#39;a test&#39;;

    /**
     * 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');
        });
    }}
The

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 of

abstract 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 expression is not very clear, you need to understand it deeply.

                                                                                                                                       

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!

Statement:
This article is reproduced at:learnku.com. If there is any infringement, please contact admin@php.cn delete