【thinkphp6源码分析一 】 最开始的地方 index.php
1 <?php 2 namespace think; 3 4 require __DIR__ . '/../vendor/autoload.php'; 5 6 // 执行HTTP应用并响应 7 $http = (new App())->http; 8 9 $response = $http->run(); 10 11 $response->send(); 12 13 $http->end($response);
代码就5句话
大概浏览一下 (仅按字面意思推测 后续会详细验证)
(1)composer类的自动加载
(2)$http = (new App())->http; 如 注释的那句话 应该是生成一个http的功能类的对象
(3)$response = $http->run(); 执行这个类的run方法 字面意思 应该是得到一个response对象
(4)$response->send(); 将response的内容发送 在这里应该是输出内容到页面
(5)$http->end($response); 结束 这个调用 干嘛的暂时猜不出来 可能是写写日志 记录下性能之类的吧
然后这五句话执行完了之后 页面就是我们熟悉的TP笑脸欢迎页面
接下来 详细看每句话的流程
从简单的入手 既然页面有这么个输出 那么从$response这个开始 毕竟这东西所见即得嘛
先打印它看看,如下,是这么一坨东西
think\response\Html {#54 ▼ #contentType: "text/html" #data: "<style type="text/css">*{ padding: 0; margin: 0; } div{ padding: 4px 48px;} a{color:#2E5CD5;cursor: pointer;text-decoration: none} a:hover{text-decoration:underline; } body{ background: #fff; font-family: "Century Gothic","Microsoft yahei"; color: #333;font-size:18px;} h1{ font-size: 100px; font-weight: normal; margin-bottom: 12px; } p{ line-height: 1.6em; font-size: 42px }</style><div style="padding: 24px 48px;"> <h1>:) </h1><p> ThinkPHP V6.0.7<br/><span style="font-size:30px;">14载初心不改 - 你值得信赖的PHP框架</span></p><span style="font-size:25px;">[ V6.0 版本由 <a href="https://www.yisu.com/" target="yisu">亿速云</a> 独家赞助发布 ]</span></div><script type="text/javascript" src="https://tajs.qq.com/stats?sId=64890268" charset="UTF-8"></script><script type="text/javascript" src="https://e.topthink.com/Public/static/client.js"></script><think id="ee9b1aa918103c4fc"></think> ◀" #charset: "utf-8" #code: 200 #allowCache: true #options: [] #header: array:1 [▼ "Content-Type" => "text/html; charset=utf-8" ] #content: null #cookie: think\Cookie {#60 ▼ #config: array:7 [▶] #cookie: [] #request: app\Request {#27 ▶} } #session: null }
上面这一坨看着挺复杂的 实际多瞅几眼就发现很熟悉
整个就是我们常见的一个http请求的response 有header content code 等等
而且里面的data属性 刚好就是那个笑脸欢迎页的html代码
这样的话 思路就很清晰了 得到一个$http类--->这个类执行后得到一个response对象(对象包含默认的一个html欢迎页)--->输出到页面-->收尾结束
接下来 我们看第二句(第一句自动加载流程这里暂时先不研究了)
$http = (new App())->http
这个APP类可以进入看一下 [tp6\vendor\topthink\framework\src\think\App.php] [借助IDE工具可以直接点击跳转]我靠。 相当复杂
官方仅有的注释说了两点
(1)这个APP是一个基础类。。
(2)这个APP类继承了 Container类
暂且不管这辆具体干嘛的 我们硬刚一会
既然有 (new App())->http 这句 那么能看得出http是属于这个APP类的一个属性
按照惯例
第一步是去APP类搜索这个属性。。结果。搜不到。搜不到的话
第二步肯定是去在父类了 继续搜索Container类。。结果发现仍然搜不到
好吧 但凡这种搜不到的 不用说了 肯定是用了啥魔术方法了
属性的话 对应的魔术方法 是__get 和 __set
搜这两个
然后 就在Container里面搜索到 __get
public function __get($name) { return $this->get($name); } /** * 获取容器中的对象实例 * @access public * @param string $abstract 类名或者标识 * @return object */ public function get($abstract) { if ($this->has($abstract)) { return $this->make($abstract); } throw new ClassNotFoundException('class not exists: ' . $abstract, $abstract); } public function make(string $abstract, array $vars = [], bool $newInstance = false) { $abstract = $this->getAlias($abstract); if (isset($this->instances[$abstract]) && !$newInstance) { return $this->instances[$abstract]; } if (isset($this->bind[$abstract]) && $this->bind[$abstract] instanceof Closure) { $object = $this->invokeFunction($this->bind[$abstract], $vars); } else { $object = $this->invokeClass($abstract, $vars); } if (!$newInstance) { $this->instances[$abstract] = $object; } return $object; }
搜到这玩意其实还是一脸懵逼 因为__get 调用了get() get()又最终调用了 make()
好在这里能看到注释了-- 获取容器中的对象实例
那么基本 这句的作用 能解释清楚了 (new App())->http 是获取一个叫http的对象实例
细节上又有好几点
(1)它用了容器 (2)http是个对象的实例 既然是实例 那么一定有生成这个http对象的类 (3)它是用make函数来生成一个类实例的
容器和make函数的详细解析暂时放一下,扫一眼代码应该能看到make一个实例的时候 可以使用bind属性里面的标识【理解这个 还是建议先过一次官方文档】
bind属性在app类里面
里面有很多类的标识
/** * 容器绑定标识 * @var array */ protected $bind = [ 'app' => App::class, 'cache' => Cache::class, 'config' => Config::class, 'console' => Console::class, 'cookie' => Cookie::class, 'db' => Db::class, 'env' => Env::class, 'event' => Event::class, 'http' => Http::class, 'lang' => Lang::class, 'log' => Log::class, 'middleware' => Middleware::class, 'request' => Request::class, 'response' => Response::class, 'route' => Route::class, 'session' => Session::class, 'validate' => Validate::class, 'view' => View::class, 'filesystem' => Filesystem::class, 'think\DbManager' => Db::class, 'think\LogManager' => Log::class, 'think\CacheManager' => Cache::class, // 接口依赖注入 'Psr\Log\LoggerInterface' => Log::class, ];
可以看到我们一开始用的http也在里面 对应 Http::class
::class 是获取这个类的完整类名(带命名空间)的意思 Http::class 就等于 think\Http
也就是说 上面 'http' => Http::class,等同于'http' => ' think\Http',
最终就是调了APP类同目录下的 think\Http [tp6\vendor\topthink\framework\src\think\Http.php]