Facade는 실제로 컨테이너에 있는 클래스의 정적 프록시입니다. 이를 통해 컨테이너에 저장된 모든 개체의 모든 메서드를 정적으로 호출할 수 있습니다. 이 문서에서는 주로 Laravel의 Facade 로딩 프로세스 및 원리에 대한 관련 정보를 소개합니다. , 도움이 필요한 친구가 참조할 수 있습니다. 그것이 모두에게 도움이 되기를 바랍니다.
머리말
이 글은 주로 라라벨의 Facade 로딩 프로세스와 원리에 대한 관련 내용을 소개하고 참고 및 학습을 위해 공유합니다. 아래에서는 자세히 설명하지 않겠습니다. 자세한 소개.
Introduction
Facades(발음: /fəˈsäd/)는 애플리케이션의 서비스 컨테이너에서 사용할 수 있는 클래스에 대한 "정적" 인터페이스를 제공합니다. 개체의 특정 메서드에 액세스하기 위해 여러 개의 네임스페이스를 사용하거나 개체를 인스턴스화할 필요가 없습니다.
use Config; class Test { public function index() { return Config::get('app.name'); } }
Facade 시작 및 등록
Facade 시작 부팅은 IlluminateFoundationBootstrapRegisterFacades에 등록됩니다.
public function bootstrap(Application $app) { Facade::clearResolvedInstances(); Facade::setFacadeApplication($app); AliasLoader::getInstance(array_merge( $app->make('config')->get('app.aliases', []), $app->make(PackageManifest::class)->aliases() ))->register(); }
기본 별칭 구성은 앱 구성 파일 아래의 별칭에서 읽혀집니다. PackageManifest는 laravel 5.5의 새로운 패키지 자동 검색 규칙입니다. 여기서는 당분간 PackageManifest 패키지에서 제공하는 별칭을 고려하지 않습니다.
그 중 array_merge는 다음 형식으로 배열을 반환합니다.
"App" => "Illuminate\Support\Facades\App" "Artisan" => "Illuminate\Support\Facades\Artisan" "Auth" => "Illuminate\Support\Facades\Auth" "Blade" => "Illuminate\Support\Facades\Blade" ...
위 코드는 AliasLoader를 통해 자동 로딩되도록 모든 Facade를 등록합니다. 핵심은 PHP의 spl_autoload_register입니다.
/** * Prepend the load method to the auto-loader stack. * * @return void */ protected function register() { if (! $this->registered) { spl_autoload_register([$this, 'load'], true, true); $this->registered = true; } }
등록이 완료되면 이후 사용 클래스는 모두 로드 기능을 통해 자동으로 로드됩니다.
참고: 여기에서 spl_autoload_register를 정의하면 마지막 매개변수가 true로 전달됩니다. 이 매개변수가 true이면 spl_autoload_register()는 대기열의 꼬리 대신 대기열의 머리에 함수를 추가합니다. (이 함수를 통해 자동 로딩이 먼저 완료됩니다.)
즉,
<?php use Config; use App\User; class Test { public function index() { Config::get('app.name'); new User(); } }
기존의 특정 클래스(AppUser)를 사용하든 별칭(Config)을 사용하든 관계없이 자동 로딩은 로드 함수를 통해 먼저 완료됩니다. 이 함수가 false를 반환하면 다른 자동 로딩 기능(예: 작곡가 psr-4)이 자동 로딩을 완료합니다.
AliasLoader의 로드 메서드에서 class_alias 함수는 주로 별칭 자동 로드를 구현하는 데 사용됩니다.
public function load($alias) { if (isset($this->aliases[$alias])) { return class_alias($this->aliases[$alias], $alias); } }
class_alias 정보 다음은 공식적인 예입니다:
class foo { } class_alias('foo', 'bar'); $a = new foo; $b = new bar; // the objects are the same var_dump($a == $b, $a === $b); //true var_dump($a instanceof $b); //false // the classes are the same var_dump($a instanceof foo); //true var_dump($a instanceof bar); //true var_dump($b instanceof foo); //true var_dump($b instanceof bar); //true
Facade loading
Facade를 사용할 때 다음과 같습니다.
<?php use Config; class Test { public function index() { Config::get('app.name'); } }
실제로 IlluminateSupportFacadesConfig 클래스가 로드됩니다(우리가 이를 등록했기 때문에 class_alias ), 다음과 같습니다:
<?php use Illuminate\Support\Facades\Config; class Test { public function index() { Config::get('app.name'); } }
그리고 모든 Facade는 IlluminateSupportFacadesFacade 클래스에서 상속되며 __callStatic 메소드는 이 기본 클래스에 정의되어 있으므로 (인스턴스화 없이) Facade를 쉽게 사용할 수 있습니다.
<?php 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); }
getFacadeRoot 메소드는 별칭 클래스의 특정 인스턴스 열을 얻는 데 사용됩니다. 모든 Facade 클래스는 getFacadeAccessor 메소드를 정의해야 합니다. 이 메서드의 가능한 반환 값은 다음과 같습니다.
문자열 유형 문자열(예: config, db)
문자열 유형 문자열 유사(예: AppServiceSomeService)
객체 특정 구체화된 객체
Closure closure
예를 들어 Config Facade의 getFacadeAccessor 메소드는 다음과 같습니다:
protected static function getFacadeAccessor() { return 'config'; }
getFacadeRoot 메소드는 getFacadeAccessor() </code의 반환 값을 기반으로 컨테이너에서 해당 실제 열 개체를 검색합니다. >. <code>getFacadeAccessor()
的返回值,从容器从取出对应的实列对象。
public static function getFacadeRoot() { $name = static::getFacadeAccessor(); if (is_object($name)) { return $name; } if (isset(static::$resolvedInstance[$name])) { return static::$resolvedInstance[$name]; } return static::$resolvedInstance[$name] = static::$app[$name]; }
由于 APP 容器中已经注册过 config 的实列
<?php //Illuminate\Foundation\Bootstrap/LoadConfiguration $app->instance('config', $config = new Repository($items));
所以 Config::get('app.name', 'dafault)
实际访问的是 Repository 实列的 get('app.name', 'default')
rrreee
rrreee에 등록되었으므로 Config::get('app.name', 'dafault)
는 실제로 Repository 열 get( 'app.name', 'default')
메소드.
위 내용은 Laravel의 Facade 로딩 과정과 원리에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!