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 중국어 웹사이트의 기타 관련 기사를 참조하세요!