ファサードは、アプリケーションのサービス コンテナ内のクラスをバインドするための「静的」インターフェイスを提供します。このメカニズムの原理は、Laravel 独自のファサードと作成されたカスタム ファサードによって実装され、IlluminateSupportFacadesFacade 基本クラスから継承されます。
(ルートを例として使用します)
config/app.php'aliases' => [ 'App' => Illuminate\Support\Facades\App::class, 'Artisan' => Illuminate\Support\Facades\Artisan::class, 'Auth' => Illuminate\Support\Facades\Auth::class, 'Blade' => Illuminate\Support\Facades\Blade::class, 'Cache' => Illuminate\Support\Facades\Cache::class, 'Config' => Illuminate\Support\Facades\Config::class, 'Cookie' => Illuminate\Support\Facades\Cookie::class, 'Crypt' => Illuminate\Support\Facades\Crypt::class, 'DB' => Illuminate\Support\Facades\DB::class, 'Eloquent' => Illuminate\Database\Eloquent\Model::class, 'Event' => Illuminate\Support\Facades\Event::class, 'File' => Illuminate\Support\Facades\File::class, 'Gate' => Illuminate\Support\Facades\Gate::class, 'Hash' => Illuminate\Support\Facades\Hash::class, 'Lang' => Illuminate\Support\Facades\Lang::class, 'Log' => Illuminate\Support\Facades\Log::class, 'Mail' => Illuminate\Support\Facades\Mail::class, 'Password' => Illuminate\Support\Facades\Password::class, 'Queue' => Illuminate\Support\Facades\Queue::class, 'Redirect' => Illuminate\Support\Facades\Redirect::class, 'Redis' => Illuminate\Support\Facades\Redis::class, 'Request' => Illuminate\Support\Facades\Request::class, 'Response' => Illuminate\Support\Facades\Response::class, 'Route' => Illuminate\Support\Facades\Route::class, //例如我们看Route,平时我们调用Route::get这样,其实是调用alias的Route,然后这个Route指向了Illuminate\Support\Facades\Route这个类,至于为什么能实现这种机制,需要继续分析 'Schema' => Illuminate\Support\Facades\Schema::class, 'Session' => Illuminate\Support\Facades\Session::class, 'Storage' => Illuminate\Support\Facades\Storage::class, 'URL' => Illuminate\Support\Facades\URL::class, 'Validator' => Illuminate\Support\Facades\Validator::class, 'View' => Illuminate\Support\Facades\View::class, 'Form' => Collective\Html\FormFacade::class, 'Html' => Collective\Html\HtmlFacade::class, ],
(phpstome を使用すると、comm+b はクラス名からクラスのソース コードを見つけることができます)
vendor/laravel/framework/src/Illuminate/Support/Facades/Route.php< ?phpnamespace Illuminate\Support\Facades;/** * @see \Illuminate\Routing\Router */class Route extends Facade{ /** * Get the registered name of the component. * * @return string */ protected static function getFacadeAccessor() //只知道Route这个类是继承了Facade,并且有一个静态方法getFacadeAccessor,返回一个router的字符串,这是一个静态方法, { return 'router'; }}
Route::get(); を使用すると、ここには静的な get メソッドがないため、Facade のマジック メソッド __callStatic
を見つけます。
__callStatic: オブジェクトに存在しない静的メソッドを呼び出すときに自動的に実行されます。
vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.phppublic static function __callStatic($method, $args) { $instance = static::getFacadeRoot(); //魔术方法调用后这里再次调用一个关键的getFacadeRoot方法,这个是静态调用 if (! $instance) { throw new RuntimeException('A facade root has not been set.'); } switch (count($args)) { case 0: return $instance->$method(); case 1: return $instance->$method($args[0]); case 2: return $instance->$method($args[0], $args[1]); case 3: return $instance->$method($args[0], $args[1], $args[2]); case 4: return $instance->$method($args[0], $args[1], $args[2], $args[3]); default: return call_user_func_array([$instance, $method], $args); } }
vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php /** * The resolved object instances. * * @var array */ protected static $resolvedInstance; //这个是一个存放实例的,这个是用来解析出实例的 public static function getFacadeRoot() { return static::resolveFacadeInstance(static::getFacadeAccessor()); //运行了2个方法,其中getFacadeAccessor作为了resolveFacadeInstance的参数来传递 } /** * Get the registered name of the component. * * @return string * * @throws \RuntimeException */ protected static function getFacadeAccessor() //返回和抛出报错信息 { throw new RuntimeException('Facade does not implement getFacadeAccessor method.'); } /** * Resolve the facade root instance from the container. * * @param string|object $name * @return mixed */ protected static function resolveFacadeInstance($name) //这个方法需要的是一个$name变量,这个变量就是getFacadeAccessor(),也就是在vendor/laravel/framework/src/Illuminate/Support/Facades/Route.php这里的返回的字符串,因为route.php重写了getFacadeAccessor方法,所以能够获取到 { if (is_object($name)) { return $name; } if (isset(static::$resolvedInstance[$name])) { return static::$resolvedInstance[$name]; } return static::$resolvedInstance[$name] = static::$app[$name]; //这里是用$app来解析container里面的对象,以前说过的IOC,将这个获取到的关键字放到$app[]来解析,然后将这个解析的container对象存放到$resolvedInstance,然后返回 }