>  기사  >  백엔드 개발  >  Laravel의 Facade 로딩 과정과 원리에 대한 자세한 설명

Laravel의 Facade 로딩 과정과 원리에 대한 자세한 설명

*文
*文원래의
2018-01-03 17:16:551268검색

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를 사용할 때 다음과 같습니다.

<?php

use Config;

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

실제로 IlluminateSupportFacadesConfig 클래스가 로드됩니다(우리가 이를 등록했기 때문에 class_alias ), 다음과 같습니다:

<?php

use Illuminate\Support\Facades\Config;

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

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

<?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 메소드는 별칭 클래스의 특정 인스턴스 열을 얻는 데 사용됩니다. 모든 Facade 클래스는 getFacadeAccessor 메소드를 정의해야 합니다. 이 메서드의 가능한 반환 값은 다음과 같습니다.

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

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

  • 객체 특정 구체화된 객체

  • Closure closure

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

protected static function getFacadeAccessor()
{
 return &#39;config&#39;;
}

getFacadeRoot 메소드는 getFacadeAccessor() 의 반환 값을 기반으로 컨테이너에서 해당 실제 열 개체를 검색합니다. >. 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') rrreee

config 열이 APP 컨테이너

rrreee에 등록되었으므로 Config::get('app.name', 'dafault) 는 실제로 Repository 열 get( 'app.name', 'default') 메소드.

관련 권장 사항:

Auth를 수정하여 Laravel의 솔트 및 비밀번호 인증 사용에 대한 자세한 설명

Laravel의 현지화 모듈에 대한 자세한 설명

자세한 설명 리소스 라우팅을 다시 작성하는 방법 라라벨에서 🎜🎜🎜

위 내용은 Laravel의 Facade 로딩 과정과 원리에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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