获取 Request 对像
在进入正题之前,需要重点说一下 make 方法。因为从上个版本使用过来的人已经开始接受 Container 这个概念了,这个新版本的增强了 Container 的功能,创建 Request 对象的精髓就在 make 方法。倒不如说整个框架核心类都在使用这个方法。我们来看一下这个方法是如何创建对象的。具体说明请看每一段的注释
```
public function make(string $abstract, array $vars = [], bool $newInstance = false)
{
// 首先说明 instances 属性是一个数组,就是主要存储容器对象
// 如果对象存在与容器中并且不需要重新创建的话,就直接从容器中获取
if (isset($this->instances[$abstract]) && !$newInstance) {
return $this->instances[$abstract];
}
// bind 属性从上一个应用初始化已经接触到了,
// 就是容器对象的绑定标识,和 instances 数组不同的是,
// 它只是存储了一个类字符串而已,需要实例化后获取对象实例,下面就是实现的该功能
// 如果 bind 标识存在
if (isset($this->bind[$abstract])) {
// 从 bind 获取
$concrete = $this->bind[$abstract];
// concrete 可能是一个类名或者是一个匿名函数
// 匿名函数直接执行
if ($concrete instanceof Closure) {
$object = $this->invokeFunction($concrete, $vars);
} else {
// 否则继续 make 创建,因为此时还没创建出对象
return $this->make($concrete, $vars, $newInstance);
}
} else {
// 如果没有在标识中 说明需要的类名真正的产出了,需要实例化。
// 其实这里才是真正的创建类,并且下面的方法直接依赖注入
$object = $this->invokeClass($abstract, $vars);
}
// 对于不需要创建实例的类 直接放在容器中管理
if (!$newInstance) {
$this->instances[$abstract] = $object;
}
// 最后返回对象
return $object;
}
```
可能到这里看的还是有点糊涂,正好在这里用 Request 创建来梳理一下。我们来看看创建 Request 的过程。
分析
下面这段代码可以的 run 方法中找到,这段代码需要仔细推敲,不然你无法知道这个 Request 对象到底是哪个?
```
//自动创建request对象
$request = $request ?? $this->app->make('request', [], true);
$this->app->instance('request', $request);
```
$newInstance 在 Request 创建时被设置为了 true,说明每次请求都需要重新创建。此时 instances 还未有 Request 对象,所以继续忽略。
在进入 bind 之前,先看看 bind 里面都有什么了?
```
array(22) {
["app"]=>
string(9) "think\App"
["cache"]=>
string(11) "think\Cache"
["config"]=>
string(12) "think\Config"
["console"]=>
string(13) "think\Console"
["cookie"]=>
string(12) "think\Cookie"
["db"]=>
string(8) "think\Db"
["env"]=>
string(9) "think\Env"
["event"]=>
string(11) "think\Event"
["http"]=>
string(10) "think\Http"
["lang"]=>
string(10) "think\Lang"
["log"]=>
string(9) "think\Log"
["middleware"]=>
string(16) "think\Middleware"
["request"]=>
string(13) "think\Request"
["response"]=>
string(14) "think\Response"
["route"]=>
string(11) "think\Route"
["session"]=>
string(13) "think\Session"
["validate"]=>
string(14) "think\Validate"
["view"]=>
string(10) "think\View"
["filesystem"]=>
string(16) "think\Filesystem"
["Psr\Log\LoggerInterface"]=>
string(9) "think\Log"
["think\Request"]=>
string(11) "app\Request"
["think\exception\Handle"]=>
string(19) "app\ExceptionHandle"
}
```
默认已经有了很多类名,这些都是框架默认的,不需要管,我们只看 request 键名和 ‘think\Request‘,还有最后两个 think\Request 和 think\exception\Handle
是在框架初始化注入进来的,不清楚的可以看上一节。think\Request 就是在那个时候注入的。
下面进入正题,很明显 'request' 在存在与 bind 中的,并且 request 的值并不是一个匿名函数,而是一个字符串 think\Request,只能继续 make 创建,找到 think\Request 对应的值 app\Request,它并不存在与 bind 中,所以直接来解析这个类名。这里大概就明白了,实际框架并没有在使用 think\Request 对象,而是 app\Request 对象。在解析后,Request 对象也被放进了容器了。下面就是请求的执行过程了。
- 空白目录
- php语法结构
- 安装与更新
- 开启调试模式及代码跟踪器
- 架构
- 源码分析
- 应用初始化
- 请求流程
- 中间件源码分析
- 请求处理源码分析
- Request源码分析
- 模板编译流程
- 路由与请求流程
- 容器
- 获取目录位置
- 入口文件
- 多应用模式及URL访问
- 依赖注入与容器
- 容器属性及方法
- Container
- App
- facade
- 中间件(middleware)
- 系统服务
- extend 扩展类库
- 笔记
- 配置
- env配置定义及获取
- 配置文件的配置获取
- 单应用模式-(配置)文件目录结构(默认)
- 多应用模式(配置)文件目录结构(配置文件)
- 配置文件
- 应用配置:app.php
- 缓存配置: cache.php
- 数据库配置:database.php
- 路由和URL配置:route.php
- Cookie配置:cookie.php
- Session配置:session.php
- 命令行配置:console.php
- 多语言配置:lang.php
- 日志配置:log.php
- 页面Trace配置:trace.php
- 磁盘配置: filesystem.php
- 中间件配置:middleware.php
- 视图配置:view.php
- 改成用yaconf配置
- 事件
- 例子:省略事件类的demo
- 例子2:完整事件类
- 例子3:事件订阅,监听多个事件
- 解析
- 路由
- 路由定义
- 路由地址
- 变量规则
- MISS路由
- URL生成
- 闭包支持
- 路由参数
- 路由中间件
- 路由分组
- 资源路由
- 注解路由
- 路由绑定
- 域名路由
- 路由缓存
- 跨域路由
- 控制器
- 控制器定义
- 空控制器、空操作
- 空模块处理
- RESTFul资源控制器
- 控制器中间件
- 请求对象Request(url参数)
- 请求信息
- 获取输入变量($_POST、$_GET等)
- 请求类型的获取与伪装
- HTTP头信息
- 伪静态
- 参数绑定
- 请求缓存
- 响应对象Response
- 响应输出
- 响应参数
- 重定向
- 文件下载
- 错误页面的处理办法
- 应用公共文件common.php
- 模型
- 模型定义及常规属性
- 模型数据获取与模型赋值
- 查询
- 数据集
- 增加
- 修改
- 删除
- 条件
- 查询范围scope
- 获取器
- 修改器
- 搜索器
- 软删除
- 模型事件
- 关联预载入
- 模型关联
- 一对一关联
- 一对多关联
- 多对多关联
- 自动时间戳
- 事务
- 数据库
- 查询构造器
- 查询合集
- 子查询
- 聚合查询
- 时间查询
- 视图查询(比join简单)
- 获取查询参数
- 快捷方法
- 动态查询
- 条件查询
- 打印sql语句
- 增
- 删
- 改
- 查
- 链式操作
- 查询表达式
- 分页查询
- 原生查询
- JSON字段
- 链接数据库配置
- 分布式数据库
- 查询事件
- Db获取器
- 事务操作
- 存储过程
- Db数据集
- 数据库驱动
- 视图
- 模板
- 模板配置
- 模板位置
- 模板渲染
- 模板变量与赋值(assign)
- 模板输出替换
- url生成
- 模板详解
- 内置标签
- 三元运算
- 变量输出
- 函数输出
- Request请求参数
- 模板注释及原样输出
- 模板继承
- 模板布局
- 原生PHP
- 模板引擎
- 视图过滤
- 视图驱动
- 验证
- 验证进阶之最终版
- 错误和日志
- 异常处理
- 日志处理
- 调试
- 调试模式
- Trace调试
- SQL调试
- 变量调试
- 远程调试
- 杂项
- 缓存
- Session
- Cookie
- 多语言
- 上传
- 扩展说明
- N+1查询
- TP类库
- 扩展类库
- 数据库迁移工具
- Workerman
- think助手工具库
- 验证码
- Swoole
- request
- app
- Response
- View
- Validate
- Config
- 命令行
- 助手函数
- 升级指导(功能的添加与删除说明)
- siyucms
- 开始
- 添加页面流程
- 列表页加载流程
- 弹出框
- 基础控制器
- 基础模型
- 快速构建
- 表单form构建
- 表格table构建
- MakeBuilder
- 前端组件
- 日期组件
- layer 弹层组件
- Moment.js 日期处理插件
- siyucms模板布局
- 函数即其变量
- 前端页面
- $.operate.方法
- $.modal.方法:弹出层
- $.common.方法:通用方法
- 被cms重写的表格options
- 自定义模板
- 搜索框
- 自定义form表单
- 获取表单搜索参数并组装为url字符串