企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# htaccess文件 ~~~ <IfModule mod_rewrite.c> Options +FollowSymlinks -Multiviews RewriteEngine On //不是目录 RewriteCond %{REQUEST_FILENAME} !-d //不是文件 RewriteCond %{REQUEST_FILENAME} !-f //重定向 RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L] </IfModule> ~~~ # 1、入口文件 用户发起的请求都会经过应用的入口文件,通常是 public/index.php文件。当然,你也可以更改或者增加新的入口文件。 通常入口文件的代码都比较简单,一个普通的入口文件代码如下: ~~~ // [ 应用入口文件 ] // 定义应用目录 define('APP_PATH', __DIR__ . '/../application/'); // 加载框架引导文件 require __DIR__ . '/../thinkphp/start.php'; ~~~ # 2、引导文件 接下来就是执行框架的引导文件,start.php文件就是系统默认的一个引导文件。在引导文件中,会依次执行下面操作: * 加载系统常量定义; * 加载环境变量定义文件; * 注册自动加载机制; * 注册错误和异常处理机制; * 加载惯例配置文件; * 执行应用; ~~~ // ThinkPHP 引导文件 // 1. 加载基础文件 require __DIR__ . '/base.php'; // 2. 执行应用 App::run()->send(); ~~~ ### 基础文件base.php * 加载系统常量定义; ![](https://img.kancloud.cn/2f/db/2fdb0f0f3f6895b1e91b8dad26a90d15_928x463.png) #### 预定义常量 预定义常量是指系统内置定义好的常量,不会随着环境的变化而变化,包括: ~~~ EXT 类库文件后缀(.php) THINK_VERSION 框架版本号 ~~~ #### 系统常量 系统常量会随着开发环境的改变或者设置的改变而产生变化。 ~~~ IS_WIN 是否属于Windows 环境 IS_CLI 是否属于命令行模式 THINK_START_TIME 开始运行时间(时间戳) THINK_START_MEM 开始运行时候的内存占用 ENV_PREFIX 环境变量配置前缀 ~~~ #### 路径常量 系统和应用的路径常量用于系统默认的目录规范,可以通过重新定义改变,如果不希望定制目录,这些常量一般不需要更改。 ~~~ DS 当前系统的目录分隔符 THINK_PATH 框架系统目录 ROOT_PATH 框架应用根目录 APP_PATH 应用目录(默认为application) CONF_PATH 配置目录(默认为APP_PATH) LIB_PATH 系统类库目录(默认为 THINK_PATH.'library/') CORE_PATH 系统核心类库目录 (默认为 LIB_PATH.'think/') TRAIT_PATH 系统trait目录(默认为 LIB_PATH.'traits/') EXTEND_PATH 扩展类库目录(默认为 ROOT_PATH . 'extend/') VENDOR_PATH 第三方类库目录(默认为 ROOT_PATH . 'vendor/') RUNTIME_PATH 应用运行时目录(默认为 ROOT_PATH.'runtime/') LOG_PATH 应用日志目录 (默认为 RUNTIME_PATH.'log/') CACHE_PATH 项目模板缓存目录(默认为 RUNTIME_PATH.'cache/') TEMP_PATH 应用缓存目录(默认为 RUNTIME_PATH.'temp/') ~~~ * 加载环境变量定义文件; # 注册自动加载机制 ~~~ // 载入Loader类 require CORE_PATH . 'Loader.php'; // 注册自动加载 \think\Loader::register(); ~~~ #### Loader::register方法 系统的自动加载由下面主要部分组成: 注册系统的自动加载方法 \think\Loader::autoload ~~~ // 注册系统自动加载 spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true); ~~~ > 当php未找到方法时,自动调用Loader::autoload加载 > 注册系统命名空间定义 加载类库映射文件(如果存在) 如果存在Composer安装,则注册**Composer**自动加载 注册extend扩展目录 > 我们的扩展类库可以放在extend 目录下,thinkphp5会自动加载 系统会调用 Loader::register()方法注册自动加载,在这一步完成后,所有符合规范的类库(包括Composer依赖加载的第三方类库)都将自动加载。 一个类库的自动加载检测顺序为: 是否定义类库映射; PSR-4自动加载检测; PSR-0自动加载检测; 可以看到,定义类库映射的方式是最高效的。 # 注册错误和异常处理机制 ~~~ // 注册错误和异常处理机制 \think\Error::register(); ~~~ ~~~ error_reporting(E_ALL); //设置用户定义的错误处理函数: set_error_handler([__CLASS__, 'appError']); //设置用户定义的异常处理函数: set_exception_handler([__CLASS__, 'appException']); register_shutdown_function([__CLASS__, 'appShutdown']); ~~~ 由三部分组成: 应用关闭方法:think\Error::appShutdown 错误处理方法:think\Error::appError 异常处理方法:think\Error::appException > 注册应用关闭方法是为了便于拦截一些系统错误。 在整个应用请求的生命周期过程中,如果抛出了异常或者严重错误,均会导致应用提前结束,并响应输出异常和错误信息 * 加载惯例配置文件; ~~~ // 加载惯例配置文件 \think\Config::set(include THINK_PATH . 'convention' . EXT); ~~~ # 5、应用初始化 ~~~ // 2. 执行应用 App::run()->send(); ~~~ App::run() 初始化一个$request-->处理->>>返回处理的$response $response->send() 系统会调用Response::send方法将最终的应用返回的数据输出到页面或者客户端,并自动转换成default_return_type参数配置的格式。 执行应用的第一步操作就是对应用进行初始化,包括: * 实例化$request对象; * 加载应用(公共)配置; `$config = self::initCommon();` * 读取数据库配置文件 * 加载扩展配置文件(由extra_config_list定义)extra目录; * 加载应用状态配置; ` 'APP_STATUS' => 'test', ` > 系统会自动尝试加载项目配置目录下面的test.php 配置文件 * 加载别名定义; * 加载行为定义; > tags文件 * 加载公共(函数)文件; > include common.php文件 * 加载扩展函数文件(由extra_file_list定义); > THINK_PATHhelper助手文件 * 注册应用命名空间; * 设置默认时区; * 加载系统语言包; # 7、路由检测 如果开启了url_route_on参数的话,会首先进行URL的路由检测。 如果一旦检测到匹配的路由,根据定义的路由地址会注册到相应的URL调度。 5.0的路由地址支持如下方式: * 路由到模块/控制器/操作; * 路由到外部重定向地址; * 路由到控制器方法; * 路由到闭包函数; * 路由到类的方法; # 8、分发请求 # 这里会初始化模块,同上应用初始化 在完成了URL检测和路由检测之后,路由器会分发请求到对应的路由地址,这也是应用请求的生命周期中最重要的一个环节。 在这一步骤中,完成应用的业务逻辑及数据返回。 建议统一使用return返回数据,而不是echo输出,如非必要,请不要使用exit或者die中断执行。 下面是系统支持的分发请求机制,可以根据情况选择: 模块/控制器/操作 这是默认的分发请求机制,系统会根据URL或者路由地址来判断当前请求的模块、控制器和操作名,并自动调用相应的访问控制器类,执行操作对应的方法。 该机制下面,首先会判断当前模块,并进行模块的初始化操作(和应用的初始化操作类似),模块的配置参数会覆盖应用的尚未生效的配置参数。 支持模块映射、URL参数绑定到方法,以及操作绑定到类等一些功能。 控制器方法 和前一种方式类似,只是无需判断模块、控制器和操作,直接分发请求到一个指定的控制器类的方法,因此没有进行模块的初始化操作。 外部重定向 可以直接分发请求到一个外部的重定向地址,支持指定重定向代码,默认为301重定向。 闭包函数 路由地址定义的时候可以直接采用闭包函数,完成一些相对简单的逻辑操作和输出。 类的方法 除了以上方式外,还支持分发请求到类的方法,包括: 静态方法: 'blog/:id'=>'\org\util\Blog::read' 类的方法:'blog/:id'=>'\app\index\controller\Blog@read' # 9、响应输出 控制器的所有操作方法都是return返回而不是直接输出,系统会调用Response::send方法将最终的应用返回的数据输出到页面或者客户端,并自动转换成default_return_type参数配置的格式。所以,应用执行的数据输出只需要返回一个正常的PHP数据即可。