【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]

 

 

 

posted on 2021-03-08 20:11  转瞬千年  阅读(880)  评论(0编辑  收藏  举报

导航