목차
"외관" 디자인 패턴이란 무엇입니까?
외관 패턴 정의
구조 다이어그램:
Laravel Appearance Component
모든 내장된 Appearance 컴포넌트의 구성 데이터는 다른 Laravel 서비스와 마찬가지로
"모양" 서비스 로드는
Laravel 서비스 공급자 구현 원칙에 대한 심층 분석에 대한 다른 기사를 읽어보셨다면 부트스트랩이 너무 낯설지 않으실 것입니다.
마지막으로
探秘 Facade
扫盲 ArrayAccess 接口
Laravel「外观」基本使用
백엔드 개발 PHP 튜토리얼 Laravel의 Facade 외관 시스템 분석

Laravel의 Facade 외관 시스템 분석

Jul 06, 2018 pm 05:13 PM
facades laravel php tutorial 원칙

이 글은 주로 Laravel의 Facade 외관 시스템에 대한 분석을 소개합니다. 이제 이를 여러분과 공유합니다. 도움이 필요한 친구들이 참고할 수 있습니다.

오늘은 Laravel의 핵심 아키텍처인 "Facade"(Appearance)에 대한 또 다른 주제를 공부하겠습니다. )".

이 기사는 Laravel에서 Facade의 작동 원리를 포괄적으로 설명하기 위해 다음 측면에서 시작됩니다. 후속 작업에서 "외관"으로 번역되는 모든 Facade에 대한 이해를 돕기 위해:

  • A "모양" 디자인 패턴에 대한 간략한 소개

  • Laravel "모양" 로딩 원리

  • Laravel "모양"의 기본 사용.

"외관" 디자인 패턴이란 무엇입니까?

외관 패턴 정의

는 하위 시스템의 인터페이스 집합에 대한 통합 입구를 제공합니다. 파사드 패턴은 이 하위 시스템을 더 쉽게 사용할 수 있도록 하는 상위 수준 인터페이스를 정의합니다.

외형 패턴은 매우 자주 사용되는 구조적 디자인 패턴입니다. 이는 외관 역할을 도입하여 클라이언트와 하위 시스템 간의 상호 작용을 단순화하고,
복잡한 하위 시스템 호출에 대한 통합 입구를 제공하며 하위 시스템 간의 결합 비용을 줄입니다. 시스템과 클라이언트가 매우 좋고 클라이언트 통화가 매우 편리합니다. - Design Pattern Java Edition

의 핵심은 클라이언트(사용자)하위 시스템(인터페이스 또는 서비스) 사이에 "외관" 역할을 도입하는 것입니다.

사용자와 하위 시스템 간의 직접적인 결합을 사용자를 위한 "외관" 클래스에서 제공하는 통합 인터페이스로 변환하여 클라이언트와 하위 시스템 간의 결합을 줄입니다.

구조 다이어그램:

Laravel의 Facade 외관 시스템 분석

"Appearance Mode"에 대해서는 Design Pattern Java Edition - Appearance Mode를 읽을 수 있습니다.

Laravel Appearance Component

Laravel의 "Appearance" 컴포넌트는 실제로 기본 클래스의 "정적 프록시"입니다. Laravel 커널에 정의된 "계약"(서비스, 계약 또는 일반적으로 Laravel에서 인터페이스라고 부르는 것이라고도 함)을 우리가 사용할 수 있도록 정적이고 호출 가능한 방식으로 다양한 "외관" 서비스로 캡슐화하는 서비스 컨테이너 " "에 있습니다.

Appearance 로딩 원리

Appearance 컴포넌트 사용 방법을 설명하기 전에 먼저 Laravel이 "appearance" 컴포넌트를 프로젝트에 로드하는 방법을 심층적으로 분석합니다. 이 단계는 "외관" 구성 요소를 효과적으로 활용하기 위한 전제 조건입니다.


Appearance 컴포넌트 구성

모든 내장된 Appearance 컴포넌트의 구성 데이터는 다른 Laravel 서비스와 마찬가지로

config/app.php

파일에 정의되어 있습니다. aliases 노드의 구성 데이터를 살펴보겠습니다.

    ...
    'aliases' => [

        'App' => Illuminate\Support\Facades\App::class,
        'Artisan' => Illuminate\Support\Facades\Artisan::class,
        ...
    ],
    ...
로그인 후 복사
외관 구성 정의 형식은

"Alias":"Appearance Class"

의 데이터 형식을 따릅니다. HTTP 요청이 수신되면 이러한 "모양과 느낌" 구성 요소가 요청 처리 단계에서 서비스에 로드됩니다. 다음으로는 출연 서비스 로딩 과정에 대해 심층 분석을 진행해보겠습니다.

모양 서비스 로드

"모양" 서비스 로드는

IlluminateFoundationBootstrapRegisterFacades::class

시작 프로그램에 의해 IlluminateFoundationHttpKernel 커널에 정의되어 완료됩니다. 부트스트랩 시작 출현 서비스

Laravel 서비스 공급자 구현 원칙에 대한 심층 분석에 대한 다른 기사를 읽어보셨다면 부트스트랩이 너무 낯설지 않으실 것입니다.

부트스트랩은 HTTP 요청

bootstrap()

을 처리하여 부팅 시작을 완료합니다. 따라서 여기서는 더 자세한 처리를 이해하기 위해 RegisterFacades 클래스에 대해 자세히 알아볼 필요가 있습니다.

<?php

namespace Illuminate\Foundation\Bootstrap;

use Illuminate\Foundation\AliasLoader;
use Illuminate\Support\Facades\Facade;
use Illuminate\Foundation\PackageManifest;
use Illuminate\Contracts\Foundation\Application;

/**
 * @link https://github.com/laravel/framework/blob/56a58e0fa3d845bb992d7c64ac9bb6d0c24b745a/src/Illuminate/Foundation/Bootstrap/RegisterFacades.php
 */
class RegisterFacades
{
    /**
     * Bootstrap the given application. 引导启动服务
     */
    public function bootstrap(Application $app)
    {
        // 清除已解析的「外观」服务实例
        Facade::clearResolvedInstances();

        // 将 Laravel 服务容器注入到「外观」服务
        Facade::setFacadeApplication($app);

        // 加载所有外观服务
        AliasLoader::getInstance(array_merge(
            $app->make(&#39;config&#39;)->get(&#39;app.aliases&#39;, []),
            $app->make(PackageManifest::class)->aliases()
        ))->register();
    }
}
로그인 후 복사
외관 서비스를 로드하면

AliasLoader

구성 요소 완성:

    먼저 모든 "외관" 서비스 구성
  • aliases

    을 구성 파일 config/app.php에서 읽은 다음

  • ; from 매니페스트 파일에서 별칭 서비스 읽기
  • $app->make(PackageManifest::class)->aliases()

    ;

  • 두 구성 배열을 결합하여
  • AliasLoader

    완료 register에 삽입합니다( 등록) .

  • 외모 서비스 등록

마지막으로

AliasLoader

로더가 모든 "외모" 서비스를 시스템에 로드하는 방법을 살펴보겠습니다.

<?php

namespace Illuminate\Foundation;

/**
 * @link https://github.com/laravel/framework/blob/56a58e0fa3d845bb992d7c64ac9bb6d0c24b745a/src/Illuminate/Foundation/AliasLoader.php
 */
class AliasLoader
{
    /**
     * Get or create the singleton alias loader instance. 获取或创建「别名加载器」单例实例。
     */
    public static function getInstance(array $aliases = [])
    {
        if (is_null(static::$instance)) {
            return static::$instance = new static($aliases);
        }

        $aliases = array_merge(static::$instance->getAliases(), $aliases);

        static::$instance->setAliases($aliases);

        return static::$instance;
    }

    /**
     * Set the registered aliases. 设置需注册别名数据。
     */
    public function setAliases(array $aliases)
    {
        $this->aliases = $aliases;
    }

    /**
     * Register the loader on the auto-loader stack. 将加载器注册到自动加载中。
     */
    public function register()
    {
        if (! $this->registered) {
            $this->prependToLoaderStack();

            $this->registered = true;
        }
    }

    /**
     * Prepend the load method to the auto-loader stack. 设置自动加载方法。
     */
    protected function prependToLoaderStack()
    {
        // 将 AliasLoader 的 load 方法作为 __autoload 的实现
        spl_autoload_register([$this, &#39;load&#39;], true, true);
    }

    /**
     * Load a class alias if it is registered.从注册过的服务中加载这个「外观」服务。
     */
    public function load($alias)
    {
        if (static::$facadeNamespace && strpos($alias, static::$facadeNamespace) === 0) {
            $this->loadFacade($alias);

            return true;
        }

        if (isset($this->aliases[$alias])) {
            return class_alias($this->aliases[$alias], $alias);
        }
    }
}
로그인 후 복사

Note

AliasLoader->register()에서 "외국인 서비스 등록"을 완료하려면 다음 두 가지 PHP 지식을 적용해야 합니다.

    PHP에 내장된 매직 메소드 사용
  • __autoload

    ;

  • PHP 클래스 별칭을 만드는 방법.
  • ➤ 1. Appearance 서비스의 동적 도입

우리는

__autoload

을 알고 있습니다. 매직 메소드의 기능은 정의되지 않은 클래스를 로드하려고 시도하여, 도입되지 않은 클래스를 사용할 때 자동으로 제공되도록 하는 것입니다. 이 수업을 소개해주세요.

更优的解决方案是通过 spl_autoload_register 函数,将自定义的类加载程序作为 __autoload 的实现,以替代默认 __autoload() 模式函数或方法的行为。

所有 prependToLoaderStack() 方法:

    /**
     * Prepend the load method to the auto-loader stack. 设置自动加载方法。
     */
    protected function prependToLoaderStack()
    {
        // 将 AliasLoader 的 load 方法作为 __autoload 的实现
        spl_autoload_register([$this, &#39;load&#39;], true, true);
    }
로그인 후 복사

就是去完成这样的作用,将 AliasLoader->load() 方法作为自动加载程序的实现,在使用「外观」服务时动态引入这个类。

➤ 2. 支持外观服务别名

我们已经了解到当「外观」服务被使用时,由 AliasLoader->load() 去自动加载这个类。

与此同时,load 方法通过 class_alias($original, $alias) 函数完成别名注册。

这样,当我们使用 App 类时实际上就是在使用 Illuminate\Support\Facades\App 类。

很完美么,我们的「狗蛋」终于与「世界上最好的语言」画上了等号。你就是我,我就是你。

到这里其实已经完成了「外观」服务工作原理分析工作的 70%

探秘 Facade

最后我们将揭开 Facade 的神秘面纱,研究一下 Laravel 是如何实现 Facade 设计模式的。

我们拿 IlluminateSupportFacadesApp 外观服务开刀,去解开类似 App::make() 静态方法使用的奥秘。

深入 FacadesApp

<?php

namespace Illuminate\Support\Facades;

class App extends Facade
{
    /**
     * Get the registered name of the component.
     */
    protected static function getFacadeAccessor()
    {
        return &#39;app&#39;;
    }
}
로그인 후 복사

我们看到它的实现内部仅仅定义了一个 getFacadeAccessor 方法,该方法的功能是获取已注册组件的名称 app;除此之外,一无所有。

看来在这里我们得不到什么有用的信息了。继续调查基类 IlluminateSupportFacadesFacade。如果你有去通便浏览全部的源码。

<?php

namespace Illuminate\Support\Facades;

use Mockery;
use RuntimeException;
use Mockery\MockInterface;

/**
 * @link https://github.com/laravel/framework/blob/5.6/src/Illuminate/Support/Facades/Facade.php
 */
abstract class Facade
{
    /**
     * Handle dynamic, static calls to the object.
     */
    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);
    }
}
로그인 후 복사

你会发现这个 Facade 基类并没有定义类似 make 的方法,那么这里能够静态调用 App::make() 看来是需要从 __callStatic 着手才行。

不过在这里我们需要再次厘清一个事实:「外观」模式的功能是什么?

将使用者与子系统从直接耦合,转变成由「外观」类提供统一的接口给使用者使用,以降低客户端与子系统之间的耦合度。

这句话的意思就是我「外观」啥也不提供,就是一层对服务(或者说组件或接口)的封装,然后以统一的方式提供给你们外部调用。

好了现在我们来看看 Facade::__callStatic 是如何获取实际的服务并调用响应的方法的吧。

  • 首先,通过 getFacadeRoot 静态方法获取实际服务的实例对象;

  • 然后,调用实例对象的相关方法并返回处理结果。

<?php

namespace Illuminate\Support\Facades;

use Mockery;
use RuntimeException;
use Mockery\MockInterface;

abstract class Facade
{
    /**
     * Get the root object behind the facade. 从 facade 中解析出真实服务的对象
     */
    public static function getFacadeRoot()
    {
        return static::resolveFacadeInstance(static::getFacadeAccessor());
    }

    /**
     * Resolve the facade root instance from the container.me 从 Laravel 服务容器中解析出真实服务的对象
     */
    protected static function resolveFacadeInstance($name)
    {
        if (is_object($name)) {
            return $name;
        }

        if (isset(static::$resolvedInstance[$name])) {
            return static::$resolvedInstance[$name];
        }

        return static::$resolvedInstance[$name] = static::$app[$name];
    }
}
로그인 후 복사

getFacadeRoot 解析对象的功能中我们可以看到:它会调用实现「外观」的 getFacadeAccessor 方法获取到组件(服务或者说接口)的名称;然后从 Laravel 服务容器 static::$app[$name](app 是在 RegisterFacades 中注册到「外观」中) 中解析出相关服务。

到这里,我们就将「外观」服务的基本工作原理给分析透彻了。

另外有关「外观」组件的一些细枝末节,如:

  • 在文档「Facades Vs. 辅助函数」一节提到的测试验证是如何实现的 Cache::shouldReceive('get')

  • 什么是「实时 Facades」。

还是需要你自行深入到 Facade 基类去一探究竟。

扫盲 ArrayAccess 接口

另外补充一个知识点就是关于 static::$app[$name] 这一句代码。你不经要问,这有啥好补充的呢,不就是一个简单获取数据么。

获取数据不假,简单也不假。

不过你仔细看一下,你会发现 static::$app 静态成员变量难道不是一个 \Illuminate\Contracts\Foundation\Application 实现实例么,怎么可以从对象中以数组的方式获取值呢?

这是因为我们的服务容器 Illuminate\Container\Container 实现了 ArrayAccess 接口。

该接口的功能是提供像访问数组一样访问对象的能力的接口,这样就可以像数组一样访问对象访问成员。

/**
 *@link https://github.com/laravel/framework/blob/5.6/src/Illuminate/Container/Container.php
 */
class Container implements ArrayAccess, ContainerContract
{
    /**
     * Get the value at a given offset. 获取一个偏移位置的值,实际上从容器中解析出服务。
     */
    public function offsetGet($key)
    {
        return $this->make($key);
    }
}
로그인 후 복사

Laravel「外观」基本使用

外观服务的一个典型使用场景是在定义路由时使用 Route::get('/', ...)。这样一看似乎「Laravel 别名服务」也就不这么神秘了。

위 내용은 이 글의 전체 내용입니다. 모든 분들의 학습에 도움이 되길 바랍니다. 더 많은 관련 내용은 PHP 중국어 홈페이지를 참고해주세요!

관련 권장 사항:

Laravel 서비스 공급자(ServiceProvider) 해석

Laravel 핵심 해석 Facades

위 내용은 Laravel의 Facade 외관 시스템 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

<gum> : Bubble Gum Simulator Infinity- 로얄 키를 얻고 사용하는 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
Nordhold : Fusion System, 설명
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora : 마녀 트리의 속삭임 - Grappling Hook 잠금 해제 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

session_start ()가 여러 번 호출되면 어떻게됩니까? session_start ()가 여러 번 호출되면 어떻게됩니까? Apr 25, 2025 am 12:06 AM

Session_Start ()로 여러 통화를하면 경고 메시지와 가능한 데이터 덮어 쓰기가 발생합니다. 1) PHP는 세션이 시작되었다는 경고를 발행합니다. 2) 세션 데이터의 예상치 못한 덮어 쓰기를 유발할 수 있습니다. 3) Session_status ()를 사용하여 반복 통화를 피하기 위해 세션 상태를 확인하십시오.

작곡가 : AI를 통한 PHP 개발 지원 작곡가 : AI를 통한 PHP 개발 지원 Apr 29, 2025 am 12:27 AM

AI는 작곡가 사용을 최적화하는 데 도움이 될 수 있습니다. 특정 방법에는 다음이 포함됩니다. 1. 종속성 관리 최적화 : AI는 종속성을 분석하고 최상의 버전 조합을 권장하며 충돌을 줄입니다. 2. 자동화 된 코드 생성 : AI는 모범 사례를 준수하는 composer.json 파일을 생성합니다. 3. 코드 품질 향상 : AI는 잠재적 인 문제를 감지하고 최적화 제안을 제공하며 코드 품질을 향상시킵니다. 이러한 방법은 기계 학습 및 자연어 처리 기술을 통해 구현되어 개발자가 효율성과 코드 품질을 향상시킬 수 있도록 도와줍니다.

session_start () 함수의 중요성은 무엇입니까? session_start () 함수의 중요성은 무엇입니까? May 03, 2025 am 12:18 AM

session_start () iscrucialinphpformanagingUsersessions.1) itiniteSanewsessionifnoneexists, 2) ResumesAnxistessions, and3) setSasessionCookieForContInuityAcrosrequests, enablingplicationsirecationSerauthenticationAndpersonalizestContent.

PHP 프레임 워크 Laravel과 YII의 차이점은 무엇입니까? PHP 프레임 워크 Laravel과 YII의 차이점은 무엇입니까? Apr 30, 2025 pm 02:24 PM

Laravel과 YII의 주요 차이점은 설계 개념, 기능적 특성 및 사용 시나리오입니다. 1. Laravel은 개발의 단순성과 즐거움에 중점을두고 Eloquentorm 및 Artisan 도구와 같은 풍부한 기능을 제공하며 빠른 개발 및 초보자에게 적합합니다. 2.YII는 성능과 효율성을 강조하고, 고 부하 애플리케이션에 적합하며, 효율적인 Activerecord 및 캐시 시스템을 제공하지만 가파른 학습 곡선이 있습니다.

최신 Laravel과 호환되는 데이터베이스 버전은 무엇입니까? 최신 Laravel과 호환되는 데이터베이스 버전은 무엇입니까? Apr 25, 2025 am 12:25 AM

Laravel10의 최신 버전은 MySQL 5.7 이상, PostgreSQL 9.6 이상, SQLite 3.8.8 이상, SQLServer 2017 이상과 호환됩니다. 이러한 버전은 JSON 데이터 유형 MySQL5.7과 같은 Laravel의 ORM 기능을 지원하여 쿼리 및 스토리지 효율성을 향상시키기 때문에 선택됩니다.

H5 : HTML5의 주요 개선 H5 : HTML5의 주요 개선 Apr 28, 2025 am 12:26 AM

HTML5는 5 가지 주요 개선 사항을 제공합니다. 1. 시맨틱 태그는 코드 선명도 및 SEO 효과를 향상시킵니다. 2. 멀티미디어 지원은 비디오 및 오디오 임베딩을 단순화합니다. 3. 형태 향상은 검증을 단순화한다. 4. 오프라인 및 로컬 스토리지는 사용자 경험을 향상시킵니다. 5. 캔버스 및 그래픽 기능은 웹 페이지의 시각화를 향상시킵니다.

데이터 처리 및 계산에 MySQL 기능을 사용하는 방법 데이터 처리 및 계산에 MySQL 기능을 사용하는 방법 Apr 29, 2025 pm 04:21 PM

MySQL 기능은 데이터 처리 및 계산에 사용될 수 있습니다. 1. 기본 사용에는 문자열 처리, 날짜 계산 및 수학 연산이 포함됩니다. 2. 고급 사용에는 복잡한 작업을 구현하기 위해 여러 기능을 결합하는 것이 포함됩니다. 3. 성능 최적화를 위해서는 WHERE 절에서 기능 사용 및 GroupBy 및 임시 테이블 사용을 피해야합니다.

권장 Laravel의 최고의 확장 팩 : 2024 필수 도구 권장 Laravel의 최고의 확장 팩 : 2024 필수 도구 Apr 30, 2025 pm 02:18 PM

2024 년의 필수 Laravel 확장 패키지는 다음과 같습니다. 1. Laraveldebugbar, 코드를 모니터링하고 디버그하는 데 사용됩니다. 2. 자세한 응용 프로그램 모니터링을 제공하는 Laraveltelescope; 3. Laravelhorizon, Redis 대기열 작업 관리. 이러한 확장 팩은 개발 효율성 및 응용 프로그램 성능을 향상시킬 수 있습니다.

See all articles