ThinkpHP 5 프레임 워 크 의 입구 에서 출력 인터페이스 까지 의 로드 프로 세 스 분석

ThinkPHP 설치
어떻게 설치 하 는 지 자세히 말 하지 않 겠 습 니 다.공식 문서-ThinkpHP 설치말 이 다 되 었 습 니 다.Composer,Git 또는 직접ThinkpHP 홈 페이지 다운로드zip 가방 에 갈 수 있 습 니 다.제 가 설치 한 버 전 은 5.0.24 입 니 다.
테스트 실행
다운로드 설치 가 완료 되면 프로젝트 가 다운로드 디 렉 터 리 가 로 컬 서버 의 프로젝트 루트 디 렉 터 리 라면 브 라 우 저 에 주소http://localhost/thinkphp5/public/를 입력 하면 ThinkpHP 5 의 기본 환영 페이지 에 들 어 갈 수 있 습 니 다.아래 그림 과 같이 ThinkpHP 5 가 설치 되 었 음 을 설명 합 니 다.
위의 주소 가 실 행 된 것 을 제외 하고 아파 치 나 Nginx 를 통 해 가상 호스트 를 설정 하여 프로젝트 에 접근 할 수 있 습 니 다.관심 있 는 것 은 인터넷 에서 구체 적 인 튜 토리 얼 을 보고 가상 호스트 를 설정 하여 접근 할 수 있 습 니 다.
다음은 본론 으로 들 어가 서 ThinkpHP 5 의 실행 절 차 를 점차적으로 분석 하 겠 습 니 다.
입구 파일(public index.php)public\index.php파일 을 열 면 입구 파일 의 원본 코드 는 다음 과 같 습 니 다.
// [        ]

//       
define('APP_PATH', __DIR__ . '/../application/');
//         
require __DIR__ . '/../thinkphp/start.php';

입구 파일 코드 는 매우 간결 하 다.
  • define('APP_PATH', __DIR__ . '/../application/');응용 디 렉 터 리 의 상수 APP 정의PATH
  • require __DIR__ . '/../thinkphp/start.php';프레임 워 크 안내 파일 불 러 오기
  • 위의 이 두 가지 역할 을 제외 하고 우 리 는 입구 파일 에 우리 자신의 상수 도 추가 로 정의 할 수 있다.예 를 들 어 코드define('PUBLIC_PATH', __DIR__ .'/../public');를 추가 하여 Public 디 렉 터 리 의 상수 와 예비 처리 등 을 정의 할 수 있다.
    프레임 가이드 파일 불 러 오기(thinkphpstart.php)
    마찬가지 로thinkphp\start.php파일 에 들 어간 후에 우 리 는 코드 가 많 지 않다 는 것 을 알 수 있다.
    namespace think;
    
    // ThinkPHP     
    // 1.       
    require __DIR__ . '/base.php';
    
    // 2.     
    App::run()->send();

    이 짧 은 두 줄 의 코드 를 통 해 우 리 는 주로 좌우 에 두 개가 있다 는 것 을 알 수 있다.
  • require __DIR__ . '/base.php';기본 파일 불 러 오기
  • App::run()->send();응용 프로그램 실행
  • 다음 두 가지 큰 점 은 이 두 가지 정도 가 무엇 을 했 는 지 구체 적 으로 소개 하 겠 습 니 다.
    기본 파일 불 러 오기(thinkphpbase.php)
    우 리 는 계속thinkphp\base.php파일 을 열 었 는데,이 파일 은 마침내 앞의 두 파일 처럼 두 줄 의 코드 만 있 는 것 이 아니 라 는 것 을 알 게 되 었 다.
    define('THINK_VERSION', '5.0.24');
    define('THINK_START_TIME', microtime(true));
    define('THINK_START_MEM', memory_get_usage());
    define('EXT', '.php');
    define('DS', DIRECTORY_SEPARATOR);
    defined('THINK_PATH') or define('THINK_PATH', __DIR__ . DS);
    define('LIB_PATH', THINK_PATH . 'library' . DS);
    define('CORE_PATH', LIB_PATH . 'think' . DS);
    define('TRAIT_PATH', LIB_PATH . 'traits' . DS);
    defined('APP_PATH') or define('APP_PATH', dirname($_SERVER['SCRIPT_FILENAME']) . DS);
    defined('ROOT_PATH') or define('ROOT_PATH', dirname(realpath(APP_PATH)) . DS);
    defined('EXTEND_PATH') or define('EXTEND_PATH', ROOT_PATH . 'extend' . DS);
    defined('VENDOR_PATH') or define('VENDOR_PATH', ROOT_PATH . 'vendor' . DS);
    defined('RUNTIME_PATH') or define('RUNTIME_PATH', ROOT_PATH . 'runtime' . DS);
    defined('LOG_PATH') or define('LOG_PATH', RUNTIME_PATH . 'log' . DS);
    defined('CACHE_PATH') or define('CACHE_PATH', RUNTIME_PATH . 'cache' . DS);
    defined('TEMP_PATH') or define('TEMP_PATH', RUNTIME_PATH . 'temp' . DS);
    defined('CONF_PATH') or define('CONF_PATH', APP_PATH); //       
    defined('CONF_EXT') or define('CONF_EXT', EXT); //       
    defined('ENV_PREFIX') or define('ENV_PREFIX', 'PHP_'); //          
    
    //     
    define('IS_CLI', PHP_SAPI == 'cli' ? true : false);
    define('IS_WIN', strpos(PHP_OS, 'WIN') !== false);
    
    //   Loader 
    require CORE_PATH . 'Loader.php';
    
    //           
    if (is_file(ROOT_PATH . '.env')) {
        $env = parse_ini_file(ROOT_PATH . '.env', true);
    
        foreach ($env as $key => $val) {
            $name = ENV_PREFIX . strtoupper($key);
    
            if (is_array($val)) {
                foreach ($val as $k => $v) {
                    $item = $name . '_' . strtoupper($k);
                    putenv("$item=$v");
                }
            } else {
                putenv("$name=$val");
            }
        }
    }
    
    //       
    \think\Loader::register();
    
    //            
    \think\Error::register();
    
    //         
    \think\Config::set(include THINK_PATH . 'convention' . EXT);

    자세히 보 니 코드 는 60 여 줄 이 있 지만 코드 의 역할 은 분명 하 다.역할 은 주로 다음 과 같은 6 가지 가 있다.
  • 사용define('', '')함 수 는 여러 시스템 상수,그리고 두 개의 환경 상수
  • 를 정의 했다.
  • loader 류(thinkphpplibrary thinkloader.php)를 도입 하여 후속 사용
  • 환경 변수 프로필 불 러 오기(환경 변수 프로필 이름.env이 파일 은 반드시 존재 하지 않 고 실제 개발 과정 에서 필요 에 따라 추 가 된 것 입 니 다)
  • 호출\think\Loader::register()등록 자동 로드 메커니즘
  • 등록 시스템 자동 로드
  • Composer자동 로드 지원
  • 등록 네 임 스페이스 정의
  • 라 이브 러 리 맵 파일 을 불 러 오고runtime캐 시 디 렉 터 리 에 존재 합 니 다classmap.php
  • 디 렉 터 리 자동 로드extend
  • 호출\think\Error::register()등록 이상 과 오류 처리 메커니즘
  • 관례 설정 파일 불 러 오기(thinkphpconvention.php)
  • 응용 프로그램(thinkphpplibrary think App.php)의 run 방법 을 실행 합 니 다.
    편 의 를 위해 서 이 run 방법의 코드 는 좀 길지 만 나 는 전체 방법 을 붙 이 는 것 을 선택 했다.나 를 때 리 지 마라.
    /**
     *       
     * @access public
     * @param  Request $request     
     * @return Response
     * @throws Exception
     */
    public static function run(Request $request = null)
    {
        $request = is_null($request) ? Request::instance() : $request;
    
        try {
            $config = self::initCommon();
    
            //   /     
            if (defined('BIND_MODULE')) {
                BIND_MODULE && Route::bind(BIND_MODULE);
            } elseif ($config['auto_bind_module']) {
                //       
                $name = pathinfo($request->baseFile(), PATHINFO_FILENAME);
                if ($name && 'index' != $name && is_dir(APP_PATH . $name)) {
                    Route::bind($name);
                }
            }
    
            $request->filter($config['default_filter']);
    
            //     
            Lang::range($config['default_lang']);
            //               
            $config['lang_switch_on'] && Lang::detect();
            $request->langset(Lang::range());
    
            //        
            Lang::load([
                THINK_PATH . 'lang' . DS . $request->langset() . EXT,
                APP_PATH . 'lang' . DS . $request->langset() . EXT,
            ]);
    
            //    app_dispatch
            Hook::listen('app_dispatch', self::$dispatch);
            //         
            $dispatch = self::$dispatch;
    
            //            URL     
            if (empty($dispatch)) {
                $dispatch = self::routeCheck($request, $config);
            }
    
            //         
            $request->dispatch($dispatch);
    
            //          
            if (self::$debug) {
                Log::record('[ ROUTE ] ' . var_export($dispatch, true), 'info');
                Log::record('[ HEADER ] ' . var_export($request->header(), true), 'info');
                Log::record('[ PARAM ] ' . var_export($request->param(), true), 'info');
            }
    
            //    app_begin
            Hook::listen('app_begin', $dispatch);
    
            //       
            $request->cache(
                $config['request_cache'],
                $config['request_cache_expire'],
                $config['request_cache_except']
            );
    
            $data = self::exec($dispatch, $config);
        } catch (HttpResponseException $exception) {
            $data = $exception->getResponse();
        }
    
        //        
        Loader::clearInstance();
    
        //         
        if ($data instanceof Response) {
            $response = $data;
        } elseif (!is_null($data)) {
            //             
            $type = $request->isAjax() ?
            Config::get('default_ajax_return') :
            Config::get('default_return_type');
    
            $response = Response::create($data, $type);
        } else {
            $response = Response::create();
        }
    
        //    app_end
        Hook::listen('app_end', $response);
    
        return $response;
    }

    이것 은 약 90 줄 의 코드 로 구체 적 으로 무엇 을 했 습 니까?주석 분석 과 결합 하여 주로 다음 과 같은 몇 가지 기능 이 있 습 니 다.
  • 첫 번 째 단계:처리 변수$request,유효 유용 성 확보 null
  • 두 번 째 단계:self::initCommon()현재 컨트롤 러 의 initCommon()방법 을 호출 하여 응용 을 초기 화하 고 설정 정 보 를 되 돌려 줍 니 다.
  • Loader::addNamespace(self::$namespace, APP_PATH);등록 네 임 스페이스
  • self::init()본 종류의 init()방법 으로 초기 화 응용
  • 각종 프로필 불 러 오기
  • 로드 행위 확장 파일
  • 공공 파일 불 러 오기
  • 언어 팩 불 러 오기
  • 응용 디 버 깅 모드 관련 처리
  • 추가 파일 을 불 러 오고 설정 항목extra_file_list의 값 으로 관련 파일 을 불 러 옵 니 다
  • date_default_timezone_set($config['default_timezone']);시스템 시간 대 설정
  • 호출Hook::listen('app_init');감청 appinit 태그 의 행동
  • 세 번 째 단계:모듈 이나 컨트롤 러 의 연결 여 부 를 판단 합 니 다
  • 네 번 째 단계:시스템 언어 설정 과 로드
  • 다섯 번 째 단계:self::routeCheck($request, $config)현재 컨트롤 러 를 불 러 오 는 routeCheck()방법 으로 경로 검 사 를 실시 합 니 다.
  • 먼저 루트 주소 설정 검 사 를 하고 캐 시 루트 를 읽 으 며 루트 파일 설정 을 가 져 오지 않 습 니 다
  • 루트 설정 없 이 모듈/컨트롤 러/조작 직접 분석
  • module 모듈 정보(모듈 명,컨트롤 러 명,조작 방법 명)되 돌려 주기
  • 여섯 번 째 단계:디 버 깅 모드 에서 경로 와 요청 정 보 를 기록 하 는 로그
  • 일곱 번 째 단계:self::exec($dispatch, $config)컨트롤 러 의 exec()방법 을 호출 하여 배포 합 니 다.
  • 사용자 요청 유형 에 따라 배포 처리 합 니 다.여 기 는 module 모듈 유형
  • 입 니 다.
  • 호출self::module()실행 모듈 을 호출 하여 모듈 배치 와 초기 화 를 하고 현재 컨트롤 러 이름과 작업 명
  • 을 가 져 오고 설정 합 니 다.
  • 8 단계:클래스 의 실례 화 를 비우 고 해당 형식의 데 이 터 를 클 라 이언 트,즉 사용자 가 본 출력 인터페이스
  • 로 출력 합 니 다.
    총결산
    본 고 는 ThinkpHP 5 의 기초 집행 절 차 를 대충 분 석 했 는데 말 이 제대로 되 지 않 은 것 도 있 고 나 에 게 말 할 필요 도 없다.왜냐하면 나 도 보충 하지 않 을 것 이기 때문이다.바로 이런 가죽 이다.하지만 틀린 말 이 라면 지적 해 주시 면 고 쳐 드 리 겠 습 니 다.이렇게 꼿꼿 합 니 다.참,도움 이 될 것 같 으 면 좋아요 누 르 고 가 야 지.고마워!

    좋은 웹페이지 즐겨찾기