목차
ThinkPHP 설치
Test run
入口文件(publicindex.php)
加载框架引导文件(thinkphpstart.php)
加载基础文件(thinkphpbase.php)
执行应用(thinkphplibrarythinkApp.php)下的run方法
3단계: 모듈 또는 컨트롤러를 바인딩할지 결정
PHP 프레임워크 ThinkPHP 입력부터 출력 인터페이스까지 TP5 프레임워크의 로딩 프로세스를 분석합니다.

입력부터 출력 인터페이스까지 TP5 프레임워크의 로딩 프로세스를 분석합니다.

Sep 16, 2021 pm 03:12 PM
thinkphp5

thinkphp 프레임워크 튜토리얼 칼럼에서는 ThinkPHP5 프레임워크의 로딩 과정을 입구부터 출력 인터페이스까지 소개하고 분석하겠습니다. 도움이 필요한 친구들에게 도움이 되길 바랍니다!

ThinkPHP 설치

설치 방법에 대해서는 자세히 설명하지 않겠습니다. 공식 문서인 ThinkPHP 설치는 매우 포괄적입니다. Composer, Git을 사용하거나 ThinkPHP 공식 홈페이지에서 직접 zip 패키지를 다운로드할 수 있습니다. 제가 설치한 버전은 5.0.24

Test run

다운로드 및 설치 후 프로젝트 다운로드 디렉토리가 프로젝트 루트 디렉토리에 있다면 로컬 서버인 경우 브라우저 http://localhost/thinkphp5/public/에 주소를 직접 입력할 수 있습니다. 아래 그림과 같이 ThinkPHP5의 기본 시작 페이지에 입력할 수 있습니다. ThinkPHP5가 성공적으로 설치되었습니다http://localhost/thinkphp5/public/,就可以进入到ThinkPHP5的默认欢迎页,如下图所示,这就说明ThinkPHP5已经安装成功

除了上面的这个方式的地址运行,我们也可以通过Apache或者Nginx配置虚拟主机实现项目的访问,有兴趣的可以网上查看具体教程,然后配置虚拟主机进行访问。

下面进入正题,我们来逐步分析ThinkPHP5的执行流程……

入口文件(publicindex.php)

打开publicindex.php文件后,我们可以看到,入口文件原始代码如下

// [ 应用入口文件 ]

// 定义应用目录
define('APP_PATH', __DIR__ . '/../application/');
// 加载框架引导文件
require __DIR__ . '/../thinkphp/start.php';
로그인 후 복사

入口文件代码很简洁,就两行代码,作用分别为

  1. define('APP_PATH', __DIR__ . '/../application/');定义应用目录的常量APP_PATH
  2. require __DIR__ . '/../thinkphp/start.php';加载框架引导文件

除了上面的这两个作用外,我们还可以额外在入口文件中,定义我们自己的常量,例如添加一行代码define('PUBLIC_PATH', __DIR__ .'/../public');定义public目录的常量以及一些预处理等

加载框架引导文件(thinkphpstart.php)

同样的,进入thinkphpstart.php文件后,我们可以知道,代码并不多

namespace think;

// ThinkPHP 引导文件
// 1. 加载基础文件
require __DIR__ . '/base.php';

// 2. 执行应用
App::run()->send();
로그인 후 복사

从这简短的两行代码,我们可以看到,主要左右有两个

  1. require __DIR__ . '/base.php';加载基础文件
  2. App::run()->send();执行应用

下面两个大点,将具体介绍这两个左右都做了什么

加载基础文件(thinkphpbase.php)

我们继续打开thinkphpbase.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);
로그인 후 복사

仔细一看,发现代码虽然有六十多行,但是,代码的作用却显而易见,作用主要有以下六点

  1. 使用define('', '')函数定义了很多个系统常量,外加两个环境常量
  2. 引入loader类(thinkphplibrarythinkloader.php),供后续使用
  3. 加载环境变量配置文件(环境变量配置文件名为.env,这个文件不一定存在,都是在实际开发过程中根据需要加上去的)
  4. 调用thinkLoader::register()注册自动加载机制

    • 注册系统自动加载
    • Composer自动加载支持
    • 注册命名空间定义
    • 加载类库映射文件,存在于runtime缓存目录下classmap.php
    • 自动加载extend目录
  5. 调用thinkError::register()注册异常和错误处理机制
  6. 加载惯例配置文件(thinkphpconvention.php)

执行应用(thinkphplibrarythinkApp.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()

      🎜🎜위의 주소 연산 방법 외에도 Apache 또는 Nginx를 통해 가상 호스트를 구성하여 액세스할 수도 있습니다. 관심 있는 사람들은 온라인으로 특정 튜토리얼을 보고 액세스할 가상 호스트를 구성할 수 있습니다. 🎜🎜본론으로 ThinkPHP5의 실행 과정을 단계별로 분석해보겠습니다...🎜🎜입력 파일(publicindex.php)🎜🎜publicindex.php 파일을 열면, 항목 파일의 원본 코드 다음 🎜rrreee🎜 항목 파일 코드는 매우 간결합니다. 단 두 줄의 코드로, 함수는 🎜
      1. define('APP_PATH', __DIR__ . '/.. /application/'); 애플리케이션 디렉토리의 상수 APP_PATH를 정의합니다.
      2. require __DIR__ '/../thinkphp/start.php';프레임워크를 로드합니다. 부팅 파일
      🎜위의 두 가지 기능 외에도 항목 파일에 자체 상수를 정의할 수도 있습니다. 예를 들어 define('PUBLIC_PATH) 코드 줄을 추가합니다. ', __DIR__ .'/../public'); 공용 디렉토리의 상수와 일부 전처리 등을 정의합니다. 🎜🎜프레임워크 부팅 파일(thinkphpstart.php)을 로드합니다. 🎜🎜마찬가지로 thinkphpstart.php 파일을 보면 코드가 많지 않다는 것을 알 수 있습니다 🎜rrreee 🎜이 짧은 두 줄의 코드에서 왼쪽과 오른쪽에 두 개의 주요 🎜
      1. require __DIR__ . '/base.php';기본 파일 로드
      2. App::run()->send();응용 프로그램 실행
      🎜다음 두 가지 주요 사항을 자세히 소개하겠습니다. What🎜🎜기본 파일(thinkphpbase.php) 로드🎜🎜계속해서 thinkphpbase.php 파일을 엽니다. 그리고 마침내 이 파일에는 이전 두 파일처럼 코드가 두 줄밖에 없다는 것을 알게 되었습니다...🎜rrreee 🎜주의깊게 살펴보면 코드가 60줄이 넘지만 코드의 기능이 분명하다는 것을 알았습니다. 🎜
      1. define('', '') 사용이 함수는 많은 시스템 상수와 두 개의 환경 상수를 정의합니다.
      2. 로더 클래스 소개( thinkphplibrarythinkloader.php) 이후 사용을 위해
      3. 환경 변수 구성 파일(.env라는 이름의 환경 변수 구성 파일 로드, 이 파일은 반드시 존재할 필요는 없으며 실제 실행 중에 필요에 따라 추가됩니다. 개발 과정)
      4. 🎜Call thinkLoader::register()자동 로딩 메커니즘 등록 🎜
        • 시스템 자동 로딩 등록
        • Composer 자동 로딩 지원
        • 네임스페이스 정의 등록
        • 런타임 캐시 디렉토리 classmap에 존재하는 클래스 라이브러리 매핑 파일 로드 .php
        • extend 목차 자동 로드
      5. thinkError::register( ) 예외 및 오류 처리 메커니즘을 등록합니다.
      6. 규칙 구성 파일 로드(thinkphpconvention.php)
      🎜애플리케이션(thinkphplibrarythinkApp.php)에서 실행 메소드를 실행합니다. 🎜🎜편의상 이 실행 메소드의 코드는 조금 길지만 그래도 전체 메소드를 게시하기로 했습니다. 🎜rrreee🎜분석에 따르면 이 약 90줄의 코드는 정확히 무엇을 하는 것인가요? 댓글에는 주로 다음과 같은 기능이 있습니다🎜
      • 첫 번째 단계: 변수 $request 처리, 유효하고 유용하며 null이 아님을 보장
      • 🎜 2단계: self::initCommon() 애플리케이션 초기화 및 구성 정보 반환을 담당하는 현재 컨트롤러에서 initCommon() 메서드를 호출합니다. 🎜
        • 로더: :addNamespace(self::$namespace, APP_PATH);네임스페이스 등록
        • 🎜self::init() code>초기화하려면 이 클래스의 init() 메서드를 호출하세요. 애플리케이션🎜<ul> <li>다양한 구성 파일 로드</li> <li>동작 확장 파일 로드</li> <li>공용 파일 로드</li> <li>언어 팩 로드</li> </ul>
        • 디버그 모드 관련 처리 적용
        • 구성 항목 extra_file_list를 통해 추가 파일 로드 관련 파일 로드extra_file_list的值去加载相关文件
        • date_default_timezone_set($config['default_timezone']);设置系统时区
        • 调用Hook::listen('app_init');监听app_init标签的行为
      • 第三步:判断是否进行模块或者控制器的绑定
      • 第四步:系统语言设置和加载
      • 第五步:self::routeCheck($request, $config)加载当前控制器的routeCheck()方法进行路由检测

        • 先进行路由地址配置检测,先读取缓存路由,不存在再导入路由文件配置
        • 无路由配置,直接解析模块/控制器/操作
        • 返回module模块信息(模块名、控制器名和操作方法名)
      • 第六步:开启调试模式下,记录路由和请求信息的日志
      • 第七步:self::exec($dispatch, $config)调用控制器中的exec()方法执行调用分发

        • 根据用户请求类型进行分发处理,这里是module模块类型
        • 调用self::module()
        • date_default_timezone_set($config['default_timezone']);시스템 시간대 설정
      • Hook::listen('app_init');을 호출하여 듣기 app_init 라벨 동작

      3단계: 모듈 또는 컨트롤러를 바인딩할지 결정

      4단계: 시스템 언어 설정 및 로딩

🎜5단계: self::routeCheck($request, $config) code>경로 감지를 위해 현재 컨트롤러의 RouteCheck() 메서드 로드🎜🎜🎜먼저 라우팅 주소 구성 감지를 수행하고, 먼저 캐시 경로를 읽고, 존재하지 않으면 라우팅 파일 구성을 가져옵니다.🎜🎜라우팅 구성 없음, 직접 모듈/컨트롤러/작업 분석🎜🎜모듈 모듈 정보(모듈 이름, 컨트롤러 이름 및 작업 방법 이름) 반환🎜🎜🎜🎜6단계: 디버그 모드를 켜서 라우팅 및 요청 정보 로그를 기록합니다🎜🎜🎜7단계: <code>self::exec($dispatch, $config)컨트롤러에서 exec() 메소드를 호출하여 호출 분배🎜🎜🎜사용자 요청 유형에 따른 분배 처리를 실행합니다. 모듈 모듈 유형은 다음과 같습니다. 🎜🎜callself::module()모듈 실행, 모듈 배포 및 초기화, 현재 컨트롤러 이름 및 작업 이름 획득 및 설정🎜🎜🎜🎜8단계: 클래스 인스턴스화 지우기 및 해당 형식으로 데이터를 출력합니다. 클라이언트, 즉 사용자가 보는 출력 인터페이스로 갑니다🎜🎜🎜Summary🎜🎜이 글에서는 ThinkPHP5의 기본 실행 과정을 대략적으로 분석해 놓았습니다. 제가 그것을 보상해드릴 수는 없기 때문에 말씀드릴 필요는 없습니다. 하지만 틀린 부분이 있으면 지적해 주시면 바로 수정해 드리겠습니다. 그런데 도움이 되셨다면 좋아요를 눌러주시고 떠나주세요. 🎜🎜

위 내용은 입력부터 출력 인터페이스까지 TP5 프레임워크의 로딩 프로세스를 분석합니다.의 상세 내용입니다. 자세한 내용은 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 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

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

SublimeText3 중국어 버전

SublimeText3 중국어 버전

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

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

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

Pagoda에 thinkphp5를 배포할 때 오류가 발생하면 어떻게 해야 합니까? Pagoda에 thinkphp5를 배포할 때 오류가 발생하면 어떻게 해야 합니까? Dec 19, 2022 am 11:04 AM

Pagoda에 thinkphp5를 배포할 때 보고된 오류에 대한 해결 방법: 1. Pagoda 서버를 열고 php pathinfo 확장을 설치하고 활성화합니다. 2. "RewriteRule ^(.*)$ index.php 콘텐츠로 ".access" 파일을 구성합니다. ?s=/$1 [QSA ,PT,L]”; 3. 웹사이트 관리에서 thinkphp의 pseudo-static을 활성화하면 됩니다.

thinkphp5 URL 재작성이 실패하면 어떻게 해야 합니까? thinkphp5 URL 재작성이 실패하면 어떻게 해야 합니까? Dec 12, 2022 am 09:31 AM

thinkphp5 URL 재작성이 작동하지 않는 해결 방법: 1. mod_rewrite.so 모듈이 httpd.conf 구성 파일에 로드되었는지 확인합니다. 2. AllowOverride None에서 None을 All로 변경합니다. 3. Apache 구성 파일 .htaccess를 "RewriteRule ^ (.*)$ index.php [L,E=PATH_INFO:$1]" 하고 저장하세요.

thinkphp5에서 요청된 URL을 얻는 방법 thinkphp5에서 요청된 URL을 얻는 방법 Dec 20, 2022 am 09:48 AM

요청된 URL을 얻는 thinkphp5의 방법: 1. 현재 URL 정보를 얻기 위해 "\think\Request" 클래스의 "$request = Request::instance();" 방법을 사용합니다. 도메인 이름을 포함한 전체 URL 주소를 얻으려면 "$request-> url()" 함수를 사용하세요.

thinkphp5 게시물이 값을 얻을 수 없으면 어떻게 해야 합니까? thinkphp5 게시물이 값을 얻을 수 없으면 어떻게 해야 합니까? Dec 06, 2022 am 09:29 AM

thinkphp5 게시물은 TP5가 strpos 함수를 사용하여 헤더의 콘텐츠 유형 값에서 app/json 문자열을 찾기 때문에 값을 얻을 수 없습니다. 해결 방법은 헤더의 콘텐츠 유형 값을 app/json으로 설정하는 것입니다.

thinkphp5 제목 표시줄 아이콘을 제거하는 방법 thinkphp5 제목 표시줄 아이콘을 제거하는 방법 Dec 20, 2022 am 09:24 AM

thinkphp5 제목 표시줄 아이콘을 제거하는 방법: 1. thinkphp5 프레임워크 공개에서 favicon.ico 파일을 찾습니다. 2. 파일을 삭제하거나 다른 사진을 선택하여 이름을 favicon.ico로 바꾸고 원본 favicon.ico 파일을 대체합니다.

thinkphp5에서 컨트롤러가 존재하지 않는다는 메시지가 표시되면 어떻게 해야 합니까? thinkphp5에서 컨트롤러가 존재하지 않는다는 메시지가 표시되면 어떻게 해야 합니까? Dec 06, 2022 am 10:43 AM

컨트롤러가 존재하지 않는다고 메시지를 표시하는 thinkphp5에 대한 해결 방법: 1. 해당 컨트롤러의 네임스페이스가 올바르게 작성되었는지 확인하고 올바른 네임스페이스로 변경합니다. 2. 해당 tp 파일을 열고 클래스 이름을 수정합니다.

ThinkPHP5에서 어제의 데이터를 쿼리하는 방법 ThinkPHP5에서 어제의 데이터를 쿼리하는 방법 Dec 05, 2022 am 09:20 AM

ThinkPHP5에서 어제의 데이터를 쿼리하는 방법: 1. ThinkPHP5 관련 파일을 엽니다. 2. "db('table')->whereTime('c_time', 'yesterday')->select();" 표현식을 통해 어제의 데이터를 쿼리할 수 있습니다. .

thinkphp5에서 오류 프롬프트를 설정하는 방법 thinkphp5에서 오류 프롬프트를 설정하는 방법 Dec 07, 2022 am 10:31 AM

thinkphp5에서 오류 프롬프트를 설정하는 방법: 1. 프로젝트 루트 디렉터리에 있는 public 폴더를 입력하고 index.php 항목 파일을 엽니다. 2. 디버그 모드 스위치에 대한 설명을 봅니다. 3. "APP_DEBUG" 상수 값을 조정합니다. 오류 메시지 프롬프트를 표시하려면 true로 설정합니다.

See all articles