对于php
的框架,不管是yii
,symfony
或者是laravel
,你们都在工做中有涉猎。对于在框架中的存放着资源包vendor
文件夹,入口文件(index.php
或者 app.php
),你们也都与他们天天碰面。可是你真的熟悉这些文件/文件夹吗?一个完整的项目是如何从一个纯净框架发展而来?各个部分又在框架这个大厦中又起到了怎么样的做用?php
总说服务器端删缓存,到底实在删除什么?laravel
... $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
文件引入进来。以前的文章讲了大半天,说的就是一个依赖关系文件的问题。咱们必需要把这个依赖关系。bootstrap
下面着重解释一下AppKernel
和Application
数组
先来看一下AppKernel.php
里面的boot
方法。这个方法是整个Appker
类的引导方法,也是核心。它里面作了以下几个工做。浏览器
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; }
这个方法写在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' ... ); }