>  기사  >  백엔드 개발  >  Laravel의 Facade 로딩 프로세스 및 원리 소개

Laravel의 Facade 로딩 프로세스 및 원리 소개

巴扎黑
巴扎黑원래의
2017-09-26 09:51:301506검색

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(&#39;app.name&#39;);
 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(&#39;foo&#39;, &#39;bar&#39;);

$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를 사용할 때:

실제로 로드된 것은 IlluminateSupportFacadesConfig 클래스(class_alias를 등록했기 때문에)는 다음과 동일합니다:


<?php

use Config;

class Test
{
 public function index()
 {
 Config::get(&#39;app.name&#39;);
 }
}

그리고 모든 Facade는 IlluminateSupportFacadesFacade 클래스에서 상속되며 __callStatic 메소드는 이 기본 클래스에 정의됩니다. 이는 Facade를 인스턴스화 없이 쉽게 사용할 수 있습니다. ).


<?php

use Illuminate\Support\Facades\Config;

class Test
{
 public function index()
 {
  Config::get(&#39;app.name&#39;);
 }
}

getFacadeRoot 메소드는 별칭 클래스의 특정 인스턴스 열을 얻는 데 사용됩니다. 우리는 모든 Facade 클래스가 getFacadeAccessor 메소드를 정의해야 한다는 것을 알고 있습니다. 이 메서드의 가능한 반환 값은 다음과 같습니다.


문자열 유형 문자열(예: config, db)

  • 문자열 유형 문자열 유사(예: AppServiceSomeService)

  • 객체 특정 구체화된 객체

  • Closure closure

  • 예를 들어 Config Facade의 getFacadeAccessor 메소드는 다음과 같습니다:

<?php

public static function __callStatic($method, $args)
{
 $instance = static::getFacadeRoot();

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

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

getFacadeRoot 메소드는 getFacadeAccessor()의 반환 값을 기반으로 컨테이너에서 해당 실제 열 개체를 검색합니다. .


protected static function getFacadeAccessor()
{
 return &#39;config&#39;;
}
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(&#39;config&#39;, $config = new Repository($items));

所以 Config::get('app.name', 'dafault) 实际访问的是 Repository 实列的 get('app.name', 'default') config 인스턴스가 APP 컨테이너

🎜🎜🎜rrreee🎜에 등록되었으므로 Config::get('app.name', 'dafault) 는 실제로 Repository에 액세스합니다. 실제 열의 get('app.name', 'default') 메서드. 🎜

위 내용은 Laravel의 Facade 로딩 프로세스 및 원리 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.