Home > PHP Framework > Laravel > body text

Implementing a simple Laravel Facade using PHP features traits

藏色散人
Release: 2022-02-09 09:09:20
forward
1939 people have browsed it

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("资源不存在");}
Copy after login

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

$article = Article::find($id);if (!$article) {
    throw new \Expection("资源不存在");}$article->delete();
Copy after login
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;}
Copy after login

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);
    }}
Copy after login
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
Copy after login
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');
        });
    }}
Copy after login
The

Article model needs to be created by yourself. Next you can see the effect:

$ php artisan test:test
Copy after login

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!

Related labels:
source:learnku.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!