源码分析之应用初始化答应大家的150粉丝福利安排
温馨提示:这篇文章已超过538天没有更新,请注意相关的内容是否还可用!
源码分析之应用初始化
答应你们的,150粉丝福利安排进阶资料,工作中打算的,免费领取
App
先来说说在中做了哪些,基本任何框架就会在此处做一些基本的操作,也就是从此处开始延伸出来。
public function __construct(string $rootPath = '')
{
$this->thinkPath = dirname(__DIR__) . DIRECTORY_SEPARATOR;
$this->rootPath = $rootPath ? rtrim($rootPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : $this->getDefaultRootPath();
$this->appPath = $this->rootPath . 'app' . DIRECTORY_SEPARATOR;
$this->runtimePath = $this->rootPath . 'runtime' . DIRECTORY_SEPARATOR;
if (is_file($this->appPath . 'provider.php')) {
$this->bind(include $this->appPath . 'provider.php');
}
static::setInstance($this);
$this->instance('app', $this);
$this->instance('think\Container', $this);
}
●从魔术的方式的参数来看,是支持自定义根目录模式的。
●设置了,,,
●绑定了默认的服务提供者,一共提供了两个php取网页源码,app\和app\,实际上你使用的就是它。具体到查看
●设置当前容器实例APP
●将App($this)范例绑定到容器中,分别是app和think\
此处应该注意的是App类是继承的,所以就是将自身例子绑定到容器中。
在此处显然整个应用就早已初始化结束了?这里我必须把一个别run的内容放到这里说,因为那儿才是框架主要的初始化工作,我并不觉得将这一个别初始化工作放在run中是合理的。
面试10家公司,收获9个offer,2020年PHP面试问题
主要的初始化
public function initialize()
{
$this->initialized = true;
$this->beginTime = microtime(true);
$this->beginMem = memory_get_usage();
// 加载环境变量
if (is_file($this->rootPath . '.env')) {
$this->env->load($this->rootPath . '.env');
}
$this->configExt = $this->env->get('config_ext', '.php');
$this->debugModeInit();
// 加载全局初始化文件
$this->load();
// 加载框架默认语言包
$langSet = $this->lang->defaultLangSet();
$this->lang->load($this->thinkPath . 'lang' . DIRECTORY_SEPARATOR . $langSet . '.php');
// 加载应用默认语言包
$this->loadLangPack($langSet);
// 监听AppInit
$this->event->trigger('AppInit');
date_default_timezone_set($this->config->get('app.default_timezone', 'Asia/Shanghai'));
// 初始化
foreach ($this->initializers as $initializer) {
$this->make($initializer)->init($this);
}
return $this;
}
●加载.env环境变量文件
●加载配置文件或者应用内的文件
●加载应用内的.php
●加载助手函数在目录下的.php
●加载配置文件
●加载应用目录下的event.php事件
●注册应用目录下的.php服务
●加载语言包
●监听事件,利用该事件可以做一些请求前的工作
●设置时区
●注入所有服务以及推进服务
服务注册
初始化过程中,进行服务注册,那么服务注册做了什么事情呢?该怎么使用的服务呢?
public function register($service, bool $force = false)
{
$registered = $this->getService($service);
if ($registered && !$force) {
return $registered;
}
if (is_string($service)) {
$service = new $service($this);
}
if (method_exists($service, 'register')) {
$service->register();
}
if (property_exists($service, 'bind')) {
$this->bind($service->bind);
}
$this->services[] = $service;
}
●服务是否注册过,如果必须强行重新注册
●实例化服务
●如果推动了原则,则必须执行方式
●如果设定了bind属性,则必须将示例绑定到容器
●最后合并到整个数组中,等待boot
服务启动
现在在初始化的之后只有以下三个服务,在$this->数组中
foreach ($this->initializers as $initializer) {
$this->make($initializer)->init($this);
}
这三个服务分别是:
think\initializer\BootService
think\initializer\Error
think\initializer\RegisterService
●Error服务是用来处理框架异常和出错的
●从字面的含义就是注册服务的
●就是启用服务的
Error处理在随后再说,这里说一下和。
当从中make出的之后
此处有个隐藏的静态方式make,每次假如首次从中make出来的例子对象就会执行make方法,当然首先需要你实现了该原则。
之后会执行Init方法。当你开启到的之后,你会发现该办法。方法内容如下:
public function init(App $app)
{
$file = $app->getRootPath() . 'runtime' . DIRECTORY_SEPARATOR . 'services.php';
$services = $this->services;
if (is_file($file)) {
$services = array_merge($services, include $file);
}
foreach ($services as $service) {
if (class_exists($service)) {
$app->register($service);
}
}
}
该方式就很奇怪了,和我想象的有点不一样。服务是直接从目录下面获取的,而非在目录下的.php中。为什么会这么呢?由于的发展,TP框架也可以提供包的手动发现的功能,这也证明了开发组在不断向社区靠拢。下面来看一下是怎样实现的。
由于这都是得益于的,所以来看一下下的.json,到最以下,你会看到后面的配置
"scripts": {
"post-autoload-dump": [
"@php think service:discover",
"@php think vendor:publish"
]
}
从配置来看,框架一共提供了两个指令,:和:。具体实现这里就不说了php取网页源码,你只必须了解包的看到是由:实现的。
也有就是此处默认注入了三个服务。
PaginatorService::class,
ValidateService::class,
ModelService::class,
最终再来看看,这个就很简单了。从命名来讲就不难看出,下面就是代码,正常的开启服务,但是此处要表明的是,服务类中需要推动了boot方法能够开启。
public function init(App $app)
{
$app->boot();
}
本文来自网络,如有侵权请联系网站客服进行删除
还没有评论,来说两句吧...