前言
对于php
的框架,无论是yii
,symfony
或者是laravel
,大家都在工作中有涉猎。对于在框架中的存放着资源包vendor
文件夹,入口文件(index.php
或者 app.php
),大家也都与他们每天碰面。但是你真的熟悉这些文件/文件夹吗?一个完整的项目是如何从一个纯净框架发展而来?各个部分又在框架这个大厦中又起到了怎么样的作用?
三、symfony
总说服务器端删缓存,到底实在删除什么?
3.1 入口文件
...
$loader = require_once __DIR__.'/../app/autoload.php';
require_once __DIR__.'/../app/bootstrap.php.cache';
$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
$request = Request::createFromGlobals();
$kernel->setRequest($request);
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
...
我们看着这个文件,发现一上来必须将autoload
文件引入进来。之前的文章讲了大半天,说的就是一个依赖关系文件的问题。我们必须要把这个依赖关系。
下面着重解释一下AppKernel
和Application
先来看一下AppKernel.php
里面的boot
方法。这个方法是整个Appker
类的引导方法,也是核心。它里面做了如下几个工作。
- 实例化
Bundle
- 实例化容器
- 实例化BIZ类
- 将每个Bundle进行引导
public function boot()
{
if (true === $this->booted) {
return;
}
if ($this->loadClassCache) {
$this->doLoadClassCache($this->loadClassCache[0], $this->loadClassCache[1]);
}
/**
* 实例化Bundles。
*/
$this->initializeBundles();
/**
* 根据cache/Jianmo/appDevDebugProjectContainer.php.meta是否存在、该文件内容(序列化)与配置文件内容是否一致
* 来判断是否需要生成cache/Jianmo/appDevDebugProjectContainer.php文件以及相关文件
* 其中appDevDebugProjectContainer.php内容如下
* 初始化appDevDebugProjectContainer类(其中methodMap对象是"类与实例化该类的方法'对照表)
* 初始化完成后,调用$this->>getContainer->get($methodMapClassName)即可以实现对该类的实例化
*/
$this->initializeContainer();
/**
* 调用appDevDebugProjectContainer->getBizService()方法
* 实例化Biz类
* 其中的初始化参数由app/config/biz.yml提供
*/
$this->initializeBiz();
/**
* AppKernel是一个重要的文件
* 无论在console命令行模式/浏览器请求模式中,都起着至关重要的作用
* 它是对于symfony的kernel进行的封装
* 该方法对于kernal进行初始化操作
*/
$this->initializeServiceKernel();
foreach ($this->getBundles() as $bundle) {
$bundle->setContainer($this->container);
$bundle->boot();
}
$this->booted = true;
}
3.1.2 实例化Bundle
3.1.2 实例化容器
这个方法写在vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php 是一个写在symfony中的底层方法,我们要在这里面详细的说一说他的功能、形成。
protected function initializeContainer()
{
$class = $this->getContainerClass();
$cache = new ConfigCache($this->getCacheDir().'/'.$class.'.php', $this->debug);
$fresh = true;
if (!$cache->isFresh()) {
$container = $this->buildContainer();
$container->compile();
$this->dumpContainer($cache, $container, $class, $this->getContainerBaseClass());
$fresh = false;
}
require_once $cache->getPath();
/**
* 对刚刚生成的app[Dev|Prod]]DebugProjectContainer类进行实例化。
* 我们去看一下该类,会发现在__construct里面
*/
$this->container = new $class();
$this->container->set('kernel', $this);
if (!$fresh && $this->container->has('cache_warmer')) {
$this->container->get('cache_warmer')->warmUp($this->container->getParameter('kernel.cache_dir'));
}
}
如果在这个时候我们打开app/cache/[prod|dev]/Jianmo/app[Dev|Prod]]DebugProjectContainer.php
文件我们就会发现,他在__construct()
中,将所有的要被加载的类名称和方法都被写到了一个大的数组当中。代码如下,我们如果想要初始化biz
这个类,只需要调用getBizService
方法。而这个方法也在当前的文件中。
...
public function __construct()
{
...
$this->methodMap = array(
'annotation_reader' => 'getAnnotationReaderService',
'app.locale_listener' => 'getApp_LocaleListenerService',
'biz' => 'getBizService'
...
);
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。