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

藏色散人
풀어 주다: 2020-01-30 19:29:36
앞으로
3946명이 탐색했습니다.

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

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 디렉터리 Helper.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 배열

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

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

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

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

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

● BootService는 활성화하는 것입니다. services

오류 처리는 나중에 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"
    ]
}
로그인 후 복사

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

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

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

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

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

ThinkPHP 관련 지식을 더 보려면 ThinkPHP 튜토리얼을 방문하세요!

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

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