ThinkPHP6 소스코드 분석 애플리케이션 초기화

藏色散人
풀어 주다: 2019-08-29 17:56:12
앞으로
3607명이 탐색했습니다.

ThinkPHP6 소스 코드 분석 - 애플리케이션 초기화

App Construct

먼저 __construct에서 수행되는 작업을 살펴보겠습니다. 기본적으로 모든 프레임워크는 여기에서 확장되는 몇 가지 기본 작업을 수행합니다.

public function __construct(string $rootPath = '')
{
    $this->thinkPath   = dirname(__DIR__) . DIRECTORY_SEPARATOR;
    $this->rootPath    = $rootPath ? rtrim($rootPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : $this->getDefaultRootPath();
    $this->appPath     = $this->rootPath . 'app' . DIRECTORY_SEPARATOR;
    $this->runtimePath = $this->rootPath . 'runtime' . DIRECTORY_SEPARATOR;
    if (is_file($this->appPath . 'provider.php')) {
        $this->bind(include $this->appPath . 'provider.php');
    }
    static::setInstance($this);
    $this->instance('app', $this);
    $this->instance('think\Container', $this);
}
로그인 후 복사

● 매직 메소드의 rootPath 매개변수로 판단하면 루트 디렉토리 경로 사용자 정의를 지원합니다.

● ThinkPath, rootPath, appPath, RuntimePath가 설정되었습니다

● 기본 서비스 공급자에 바인딩되어 있으며, appReques, appExceptionHandle 총 2개가 제공됩니다. 실제로 사용하는 Request입니다. 구체적으로 appPath로 이동하여 view

● 현재 컨테이너 인스턴스 APP를 설정하세요

● App($this) 인스턴스를 app과 thinkContainer

여기서 App 클래스가 Container를 상속한다는 점에 유의해야 합니다. 그래서 그것은 self 인스턴스가 컨테이너에 바인딩되어 있습니다.

여기서 애플리케이션 전체가 초기화된 것 같은데요? 여기서는 Request run의 내용 중 일부를 여기에 넣어야 합니다. 왜냐하면 그것이 프레임워크의 주요 초기화 작업이기 때문입니다. 초기화 작업의 이 부분을 Request run에 넣는 것은 합리적이지 않다고 생각합니다.

기본 초기화

public function initialize()
{
    $this->initialized = true;
    $this->beginTime = microtime(true);
    $this->beginMem  = memory_get_usage();
    // 加载环境变量
    if (is_file($this->rootPath . '.env')) {
        $this->env->load($this->rootPath . '.env');
    }
    $this->configExt = $this->env->get('config_ext', '.php');
    $this->debugModeInit();
    // 加载全局初始化文件
    $this->load();
    // 加载框架默认语言包
    $langSet = $this->lang->defaultLangSet();
    $this->lang->load($this->thinkPath . 'lang' . DIRECTORY_SEPARATOR . $langSet . '.php');
    // 加载应用默认语言包
    $this->loadLangPack($langSet);
    // 监听AppInit
    $this->event->trigger('AppInit');
    date_default_timezone_set($this->config->get('app.default_timezone', 'Asia/Shanghai'));
    // 初始化
    foreach ($this->initializers as $initializer) {
        $this->make($initializer)->init($this);
    }
    return $this;
}
로그인 후 복사

● .env 환경 변수 파일 로드

● 구성 파일 및 애플리케이션의 파일 로드

● 애플리케이션에서 common.php 로드

● thinkPath 디렉터리 .php

● 구성 파일 로드

● 애플리케이션 디렉터리에 event.php 이벤트 로드

● 애플리케이션 디렉터리에 service.php 서비스 등록

● 언어 팩 로드

● 듣기 AppInit 이벤트를 사용하여 사전 요청 작업을 할 수 있습니다

● 시간대 설정

● 모든 서비스 주입 및 서비스 시작

서비스 등록

초기화 과정에서 서비스 등록이 수행됩니다. 그러면 서비스 등록은 무엇을 합니까? 서비스 이용 방법

public function register($service, bool $force = false)
{
    $registered = $this->getService($service);
    if ($registered && !$force) {
        return $registered;
    }
    if (is_string($service)) {
        $service = new $service($this);
    }
    if (method_exists($service, 'register')) {
        $service->register();
    }
    if (property_exists($service, 'bind')) {
        $this->bind($service->bind);
    }
    $this->services[] = $service;
}
로그인 후 복사

● 서비스 등록 여부 강제 재등록이 필요한 경우

● 서비스 인스턴스화

● 등록 메소드가 구현된 경우 등록 메소드를 실행해야 함

● 바인딩 속성이 다음과 같은 경우 설정한 후에는 서비스 인스턴스를 컨테이너

●에 바인딩하고 마지막으로 전체 서비스 배열에 병합해야 하며 boot

서비스가 시작되기를 기다립니다

현재 초기화 중에는 다음 세 가지 서비스만 있습니다. $this->initializers array

foreach ($this->initializers as $initializer) {
        $this->make($initializer)->init($this);
}
로그인 후 복사

이 세 가지 서비스는 다음과 같습니다:

think\initializer\BootService
think\initializer\Error
think\initializer\RegisterService
로그인 후 복사

● 오류 서비스는 프레임워크 예외 및 오류를 처리하는 데 사용됩니다.

● RegisterService는 말 그대로 서비스 등록을 의미합니다.

● BootService는 서비스를 활성화하는 것입니다

오류 처리는 나중에 RegisterService와 BootService에 대해 설명하겠습니다.

Container에서 RegisterService를 만들 때

Container에서 인스턴스 객체를 처음 만들 때마다 make 메소드가 숨겨져 있습니다. 물론 이 메소드를 먼저 구현해야 합니다.

그러면 Init 메서드가 실행됩니다. RegisterService에 들어가면 이 메소드가 보입니다. 방법 내용은 다음과 같습니다.

public function init(App $app)
{
    $file = $app->getRootPath() . 'runtime' . DIRECTORY_SEPARATOR . 'services.php';
    $services = $this->services;
    if (is_file($file)) {
        $services = array_merge($services, include $file);
    }
    foreach ($services as $service) {
        if (class_exists($service)) {
            $app->register($service);
        }
    }
}
로그인 후 복사

이 방법은 제가 상상했던 것과는 조금 다른 아주 이상한 방법입니다. 서비스는 config 디렉터리의 service.php가 아닌 런타임 디렉터리에서 직접 가져옵니다. 왜 이런 일이 발생합니까? Composer의 개발로 인해 TP 프레임워크는 패키지의 자동 검색도 제공할 수 있으며 이는 개발 팀이 지속적으로 커뮤니티에 더 가까이 다가가고 있음을 증명합니다. 이것이 어떻게 달성되는지 살펴 보겠습니다.

이건 모두 작곡가 때문이므로 rootPath 아래의 작곡가.json을 살펴보세요. 맨 아래로 이동하면 다음 구성을 찾을 수 있습니다.

"scripts": {
    "post-autoload-dump": [
        "@php think service:discover",
        "@php think vendor:publish"
    ]
}
로그인 후 복사

구성 관점에서 프레임워크는 총 2가지 지침을 제공합니다. , 서비스:검색 및 공급업체:게시. 여기서는 구체적인 구현에 대해 다루지 않겠습니다. 패키지 검색이 service:discover에 의해 구현된다는 점만 알면 됩니다.

또한 여기에는 기본적으로 세 가지 서비스가 주입됩니다.

PaginatorService::class,
ValidateService::class,
ModelService::class,
로그인 후 복사

마지막으로 BootService를 살펴보겠습니다. 이는 매우 간단합니다. 네이밍 측면에서 보면 아래 코드는 서비스를 정상적으로 시작하기 위한 코드라고 보면 어렵지 않으나, 여기서 설명할 점은 서비스 클래스에 boot 메소드를 구현해야 서비스를 시작할 수 있다는 점이다.

public function init(App $app)
{
    $app->boot();
}
로그인 후 복사

위는 전체 어플리케이션의 초기화이며, 구체적인 내용은 추후 다루도록 하겠습니다.

이 기사는 ThinkPHP 프레임워크 기술 기사 칼럼에서 발췌한 것입니다: http://www.php.cn/phpkj/thinkphp/

위 내용은 ThinkPHP6 소스코드 분석 애플리케이션 초기화의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:learnku.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿