What's a Facade? I hope it's useful for PHPer

What is the Facade? At present, it is a class that is used to facilitate the static method call of the original class (undefined static method).
The specific implementation of Facade is as follows:
First look at the core document:
\thinkphp\base.php
`//Register static proxy of core class
Facade::bind([

facade\App::class      => App::class,
facade\Build::class    => Build::class,
facade\Cache::class    => Cache::class,
facade\Config::class   => Config::class,
facade\Cookie::class   => Cookie::class,
facade\Debug::class    => Debug::class,
facade\Env::class      => Env::class,
facade\Hook::class     => Hook::class,
facade\Lang::class     => Lang::class,
facade\Log::class      => Log::class,
facade\Request::class  => Request::class,
facade\Response::class => Response::class,
facade\Route::class    => Route::class,
facade\Session::class  => Session::class,
facade\Url::class      => Url::class,
facade\Validate::class => Validate::class,
facade\View::class     => View::class,]);

You can see the binding method similar to that in the container. Find the corresponding binding method as follows:

` /**

 * Static proxy of binding class
 * @static
 * @access public
 * @param  string|array  $name    Class ID
 * @param  string        $class   Class name
 * @return object
 */
public static function bind($name, $class = null)
{
    if (__CLASS__ != static::class) {
        return self::__callStatic('bind', func_get_args());
    }

    if (is_array($name)) {
        self::$bind = array_merge(self::$bind, $name);
    } else {
        self::$bind[$name] = $class;
    }
}`
//You can see that it is also put into an array $bind.

Here, notice the following method of registering class alias in thinkphpbase.php file, which can realize class alias direct access to class (see here for yourself)
`//Register class library alias
Loader::addClassAlias([

'App'      => facade\App::class,
'Build'    => facade\Build::class,
'Cache'    => facade\Cache::class,
'Config'   => facade\Config::class,
'Cookie'   => facade\Cookie::class,
'Db'       => Db::class,
'Debug'    => facade\Debug::class,
'Env'      => facade\Env::class,
'Facade'   => Facade::class,
'Hook'     => facade\Hook::class,
'Lang'     => facade\Lang::class,
'Log'      => facade\Log::class,
'Request'  => facade\Request::class,
'Response' => facade\Response::class,
'Route'    => facade\Route::class,
'Session'  => facade\Session::class,
'Url'      => facade\Url::class,
'Validate' => facade\Validate::class,
'View'     => facade\View::class,]);

How to call static methods, such as

\Cache::set('name','value');

For this method, how to call the set method at a specific time? First, use the alias mechanism of the above class to find the corresponding facade cache:: class, which is actually called. Then let's look at the contents of this class:

namespace think\facade;

use think\Facade;

class Cache extends Facade
{
}

You can see that there is no content, so where is the set method? Here we use a method that will be called if the static method call of PHP fails. In the Facade class, there are:

 // Call the method of the actual class
    public static function __callStatic($method, $params)
    {
        return call_user_func_array([static::createFacade(), $method], $params);
    }
//When an invocation method is invoked in a static context, __callStatic() is called.    

In other words, when the set method is not called, the method will be called, that is, it is actually called

call_user_func_array([static::createFacade(), $method], $params)

In fact:

/**
     * Create a Facade instance
     * @static
     * @access protected
     * @param  string    $class          Class name or ID
     * @param  array     $args           variable
     * @param  bool      $newInstance    Whether to create a new instance every time
     * @return object
     */
    protected static function createFacade($class = '', $args = [], $newInstance = false)
    {
        $class       = $class ?: static::class;
        $facadeClass = static::getFacadeClass();
        if ($facadeClass) {
            $class = $facadeClass;
        } elseif (isset(self::$bind[$class])) {
            $class = self::$bind[$class];
        }

        if (static::$alwaysNewInstance) {
            $newInstance = true;
        }
        return Container::getInstance()->make($class, $args, $newInstance);
    }

You can see the last sentence, which is actually the set method of the instance of Cache::class (obtained through the container).

phper always encounters some problems and bottlenecks in its advanced stage. There is no sense of direction when it writes more business code. I don't know where to start to improve. For this, I collated some data, including but not limited to: distributed architecture, high scalability, high performance, high concurrency, server performance tuning, TP6, laravel, YII2, Redis, Swoole, Swoft, Kafka, Mysql optimization, shell Script, Docker, microservice, Nginx and other advanced dry goods can be shared for free Please poke here.

Tags: PHP Session Laravel Redis

Posted on Fri, 08 Nov 2019 04:22:41 -0500 by unbreakable9