企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# TP5架构 [TOC] * * * * * ## 一、架构总览 ~~~ ThinkPHP5.0应用基于`MVC`:模型、视图、控制器 的方式组织。 MVC: 输入、处理、输出相分离 5.0的URL访问受路由决定,关闭或没有匹配到,则基于: `http://serverName/index.php(或者其它应用入口文件)/模块/控制器/操作/参数/值…` ~~~ ***** ## 二、基本概念 * 入口文件: `index.php` 、 `admin.php` 、 `think`... * 应用: `think\App` * 模块: `一个应用包括多个模块: 模块有自己的配置文件、公共文件、类库文件`、 `5.0支持单一模块架构设计(需配置)` * 控制器(类):` 一个模块包含多个控制器(负责响应请求)`、`5.0可以通过路由跳过控制器,直接调用模型或其他类` ~~~ namespace app\index\controller; class Index { public function index() { return 'hello,thinkphp!'; } } ~~~ * 操作(方法): `一个控制器包含多个操作(方法)` ~~~ namespace app\index\controller; class Index { public function index() { return 'index'; } public function hello($name) { return 'Hello,'.$name; } } ~~~ * 模型: `完成实际的业务逻辑和数据封装,返回和格式无关的数据`、`惰性连接`、`支持多层设计:逻辑层、服务层、事件层` * 视图:`视图根据不同的需求,来决定调用模板引擎进行内容解析后输出还是直接输出。` * 驱动:`系统很多的组件都采用驱动式设计,从而可以更灵活的扩展。` * 行为:`行为(Behavior)是在预先定义好的一个应用位置执行的一些操作。` * 命名空间: ~~~ 要执行行为,首先要在应用程序中进行行为侦听,例如: // 在app_init位置侦听行为 \think\Hook::listen('app_init'); 然后对某个位置进行行为绑定: // 绑定行为到app_init位置 \think\Hook::add('app_init','\app\index\behavior\Test'); ~~~ ***** ## 三、生命周期 1. 入口文件 `public\index.php`:`定义常量等` ~~~ // 应用入口文件 // 定义项目路径 define('APP_PATH', __DIR__ . '/../application/'); // 加载框架引导文件 require __DIR__ . '/../thinkphp/start.php'; ~~~ 2. 框架引导文件 `start.php` ~~~ 1. 加载系统常量定义 2. 加载环境变量定义文件 3. 注册自动加载机制 4. 注册错误和异常处理机制 5. 加载惯例配置文件 6. 执行应用 ~~~ 3. 注册自动加载 `Loader::register()` ~~~ 1. 注册系统的自动加载方法 \think\Loader::autoload 2. 注册系统命名空间定义 3. 加载类库映射文件(如果存在) 4. 如果存在Composer安装,则注册**Composer**自动加载 5. 注册extend扩展目录 ~~~ 4. 注册错误和异常机制 `Error:register()` ~~~ * 应用关闭方法: think\Error::appShutdown * 错误处理方法: think\Error::appError * 异常处理方法: think\Error::appException ~~~ 5. 应用初始化 ~~~ * 加载应用(公共)配置; * 加载扩展配置文件(由extra_config_list定义); * 加载应用状态配置; * 加载别名定义; * 加载行为定义; * 加载公共(函数)文件; * 注册应用命名空间; * 加载扩展函数文件(由extra_file_list定义); * 设置默认时区; * 加载系统语言包; ~~~ 6. URL访问检测 `PATH_INFO检测`、`URL后缀检测` 5.0的URL访问必须是`PATH_INFO`方式(或兼容方式): `http://serverName/index.php/index/index/hello/val/value` 普通方式: `http://serverName/index.php?s=/index/index/hello&val=value` 命令行访问: `$php index.php index/index/hello/val/value...` 获取到正常的`$_SERVER['PATH_INFO']`参数后才能继续。 7. 路由检测 `url_route_on`参数开启,会首先检测URL路由: 5.0的地址支持: ~~~ * 路由到模块/控制器/操作; * 路由到外部重定向地址; * 路由到控制器方法; * 路由到闭包函数; * 路由到类的方法; ~~~ 路由检测无效,则按照 *模块/控制器/操作* 分析识别 8. 分发请求 `应用请求的生命周期中最重要的环节`:`完成应用的业务逻辑及数据返回` 支持的分发请求机制: ~~~ * 模块/控制器/操作 * 控制器方法 * 外部重定向 * 闭包函数 * 类的方法: * 静态方法:'blog/:id'=>'\org\util\Blog::read' * 类的方法:'blog/:id'=>'\app\index\controller\Blog@read' ~~~ 9. 响应输出 方法调用`return` 返回数据,系统会调用`Response::send`将应用返回的数据输出到页面,或客户端。,并自动转换成`default_return_type`参数配置的格式。 10. 应用结束 应用数据响应输出后,系统会进行日志保存写入操作。 ***** ## 四、入口文件 **入口文件的任务:** * [定义框架路径、项目路径] * [定义系统常量] * 载入框架入口文件 ***** **5.0默认入口文件**(可修改): `public\index.php` ~~~ // 定义应用目录 define('APP_PATH', __DIR__ . '/../application/'); // 加载框架引导文件 require __DIR__ . '/../thinkphp/start.php'; ~~~ (给`APP_PATH`定义绝对路径会提高系统的加载效率。) ***** **框架引导文件** `base.php` : 不会主动执行应用 `start.php` : 会主动执行 ~~~ // 定义应用目录 define('APP_PATH', __DIR__ . '/../application/'); // 加载框架基础引导文件 require __DIR__ . '/../thinkphp/base.php'; // 添加额外的代码 // ... // 执行应用 \think\App::run()->send(); ~~~ ***** ## 五、URL访问 **url设计:** * 典型方式: http://serverName/index.php(或者其它应用入口文件)/模块/控制器/操作/[参数名/参数值...] * 命令行模式:$ php.exe index.php(或者其它应用入口文件) 模块/控制器/操作/[参数名/参数值...] 命令行模式:$ php.exe index.php(或者其它应用入口文件) 模块/控制器/操作?参数名=参数值&... * 兼容模式: http://serverName/index.php(或者其它应用入口文件)?s=/模块/控制器/操作/[参数名/参数值...] **URL大小写** `默认情况下,URL不区分大小写`。 如需要区分大小写,需改配置: ~~~ // 关闭URL中控制器和操作名的自动转换 'url_convert' => false, ~~~ `路由规则中定义的路由地址,区分大小写` **隐藏入口文件** 配置过程: ~~~ 1.httpd.conf配置文件中加载了mod_rewrite.so模块 2.AllowOverride None 将None改为 All 3.在应用入口文件同级目录添加.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> ~~~ &nbsp;&nbsp;&nbsp;&nbsp; nginx服务器配置见`URL重写` ***** ## 六、模块设计 **应用目录结构** ~~~ ├─application 应用目录(可设置) │ ├─common 公共模块目录(可选) │ ├─common.php 公共函数文件 │ ├─route.php 路由配置文件 │ ├─database.php 数据库配置文件 │ ├─config.php 应用配置文件 │ ├─module1 模块1目录 │ │ ├─config.php 模块配置文件 │ │ ├─common.php 模块函数文件 │ │ ├─controller 控制器目录 │ │ ├─model 模型目录(可选) │ │ ├─view 视图目录(可选) │ │ └─ ... 更多类库目录 │ │ │ ├─module2 模块2目录 │ │ ├─config.php 模块配置文件 │ │ ├─common.php 模块函数文件 │ │ ├─controller 控制器目录 │ │ ├─model 模型目录(可选) │ │ ├─view 视图目录(可选) │ │ └─ ... 更多类库目录 ~~~ `common`模块默认禁止直接访问,用于放置公共类库。 **模块类库** 模块命名空间:`app\模块名` ~~~ // index模块的Index控制器类 app\index\controller\Index // index模块的User模型类 app\index\model\User ~~~ `app`可修改,配置中的: `'app_namespace' => 'application',` **模块和控制器隐藏** 一个模块时的模块绑定,在入口文件中添加: ~~~ // 绑定当前访问到index模块 define('BIND_MODULE','index'); ~~~ 绑定后url可省略模块名: `http://serverName/index.php/控制器/操作/[参数名/参数值...]` 如果只有一个模块,一个控制器,可在应用公共文件中绑定模块和控制器: ~~~ // 绑定当前访问到index模块的index控制器 define('BIND_MODULE','index/index'); ~~~ 只需url访问: `http://serverName/index.php/操作/[参数名/参数值...]` **单一模块** 应用只有一个模块,可简化应用结构: 1.改配置 ~~~ // 关闭多模块设计 'app_multi_module' => false, ~~~ 2.改目录结构 ~~~ ├─application 应用目录(可设置) │ ├─controller 控制器目录 │ ├─model 模型目录 │ ├─view 视图目录 │ ├─ ... 更多类库目录 │ ├─common.php 函数文件 │ ├─route.php 路由配置文件 │ ├─database.php 数据库配置文件 │ └─config.php 配置文件 ~~~ 3.命名空间 ~~~ app\controller\Index app\model\User ~~~ 4.url访问 `http://serverName/index.php(或者其它应用入口)/控制器/操作/[参数名/参数值...]` **** ***** ## 七、命名空间 ***** ## 八、自动加载 ***** ## 九、Traits引入 ***** ## 十、API友好 *****