网络编程
位置:首页>> 网络编程>> php编程>> PHP Laravel门面的实现原理详解

PHP Laravel门面的实现原理详解

作者:自由de单车  发布时间:2023-05-25 06:42:36 

标签:Laravel,门面

环境

Laravel 5.4

原理

在Laravel中,门面为应用服务容器中绑定的类提供了一个“静态”接口,使得我们可以不用new这些类出来,就可以直接通过静态接口调用这些类中的方法。

下面我们先看看一个门面类是怎么定义的:

<?php

namespace App\Facades;

use Illuminate\Support\Facades\Facade;

class Player extends Facade
{

   protected static function getFacadeAccessor() {
       return 'player';
   }

}

门面类都继承自Illuminate\Support\Facades\Facade父类,这个父类中有一个魔术方法:

/**
    * Handle dynamic, static calls to the object.
    *
    * @param  string  $method
    * @param  array   $args
    * @return mixed
    *
    * @throws \RuntimeException
    */
   public static function __callStatic($method, $args)
   {
       $instance = static::getFacadeRoot();

       if (! $instance) {
           throw new RuntimeException('A facade root has not been set.');
       }

       return $instance->$method(...$args);
   }

当我们静态调用一个不存在的方法时,例如Player::playOneSong(),这个魔术方法就会被调用。它通过getFacadeRoot()方法创建出一个对象,然后在这个对象上真正执行我们的方法。

再看看getFacadeRoot()方法:

/**
    * Get the root object behind the facade.
    *
    * @return mixed
    */
   public static function getFacadeRoot()
   {
       return static::resolveFacadeInstance(static::getFacadeAccessor());
   }

这里通过我们自定义门面类中的getFacadeAccessor方法,获取到一个service_id(暂且这么叫吧),然后传给resolveFacadeInstance方法。

再往下看resolveFacadeInstance方法:

/**
    * Resolve the facade root instance from the container.
    *
    * @param  string|object  $name
    * @return mixed
    */
   protected static function resolveFacadeInstance($name)
   {
       if (is_object($name)) {
           return $name;
       }

       if (isset(static::$resolvedInstance[$name])) {
           return static::$resolvedInstance[$name];
       }

       return static::$resolvedInstance[$name] = static::$app[$name];
   }

通过static::$app[$name]从服务容器中获取 key 为name的对象,服务容器会帮我们实例化出对应的对象(前提是已经绑定好)。

服务容器$app是一个对象,但它实现了ArrayAccess接口,所以可以用这种数组的方式访问。

获取到对象后,放入到static::$resolvedInstance静态变量中,这样下次再获取相同对象时,就不用重复实例化了。

来源:https://blog.csdn.net/ljfrocky/article/details/128944416

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com