對於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' ... ); }