Bundle系統
bundle類似於其他軟體中的插件,但更好。關鍵區別在於:Symfony中的每一樣東西都是bundle,包括框架核心功能,以及你寫的程式碼。 bundle是Symfony體系中的一等公民。這就給了你一個彈性架構,既可以使用 第三方bundle 中的預建功能,也可以發佈你自己的bundle。 bundle可以讓你在自己的程式中挑選「開啟哪個功能」變得容易,還能以你的方式來優化。
在本文中你可以學到bundle基礎知識,「最佳實踐」中有大章節專注於bundle的組織和最佳實踐。
一個bundle,就是一組結構化的文件,存於一個「用來實現某個獨立功能」的目錄中。你可以創建一個BlogBundle,一個ForumBundle,或者是一個管理用戶的bundle(很多類似bundle已經作為開源專案存在)。每個目錄都包含著關乎那個功能的所有東西,包括php文件,模板,css,js文件,tests,以及其他。每一個功能的子項都存在於bundle中,每一個功能都存在於bundle中。
要在你的程式中使用bundle,必須透過AppKernel
類別的registerBundles()
方法來註冊並使用它們:
// app/AppKernel.phppublic function registerBundles(){ $bundles = array( new Symfony\Bundle\FrameworkBundle\FrameworkBundle(), new Symfony\Bundle\SecurityBundle\SecurityBundle(), new Symfony\Bundle\TwigBundle\TwigBundle(), new Symfony\Bundle\MonologBundle\MonologBundle(), new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(), new Symfony\Bundle\DoctrineBundle\DoctrineBundle(), new Symfony\Bundle\AsseticBundle\AsseticBundle(), new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(), new AppBundle\AppBundle(), ); if (in_array($this->getEnvironment(), array('dev', 'test'))) { $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle(); $bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle(); $bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle(); } return $bundles;
registerBundles()
方法可以讓你完全控制在程式中使用哪個bundle(包括Symfony的核心bundle)。
bundle可以存在於任何地方,只要它能夠被自動載入(透過app/autoload.php
中所配置的自動載入器實作)
創建一個Bundle ¶
#Symfony標準版內建了超好用的指令,用來幫你創造全功能bundle。當然,手動建立bundle也一樣容易。
為了展示一個簡單的bundle系統,我們建立一個全新的AcmeTestBundle並開啟它。
Acme
部分只是個假名,實戰中應被一些「vendor」名字替換掉,以代表你或你所在的組織(例如ABCTestBundle代表某個名為ABC
的公司)
從新建一個src/Acme/TestBundle/
目錄開始,再新建一個AcmeTestBundle. php
檔案:
// src/Acme/TestBundle/AcmeTestBundle.phpnamespace Acme\TestBundle; use Symfony\Component\HttpKernel\Bundle\Bundle; class AcmeTestBundle extends Bundle { }
AcmeTestBundle遵守bundle命名約定。你可以選擇簡化bundle名稱為TestBundle,透過把類別名稱改為TestBundle(同時修改檔案名稱 TestBundle.php
)
這個空類別就是你在創建全新bundle時,唯一需要的東西。儘管一般情況下確實是空的,但這個類別格外強大,專門用於定制該bundle的各種行為。
現在你已經創建了bundle,在AppKernel
類別中開啟它:
// app/AppKernel.phppublic function registerBundles(){ $bundles = array( // ... // register your bundle / 注册你的bundle new Acme\TestBundle\AcmeTestBundle(), ); // ... return $bundles;}
儘管目前啥也沒做,AcmeTestBundle已經可以使用。
就這麼簡單,Symfony也提供了命令列介面,用於產生一個基本的bundle骨架:
$ php bin/console generate:bundle --namespace=Acme/TestBundle
bundle骨架包括控制器、模板和路由資源等,而且都可以自訂。在後面的Symfony命令列工具小節,你可以學到更多。
不管是建立新bundle或使用第三方bundle,應確保bundle被 registerBundles()
開啟。當使用 generate:bundle
指令時,Symfony替你註冊完成了。
Bundle目錄結構 ¶
bundle目錄是簡單且有彈性的。在預設條件下,bundle系統遵循一組命名約定,以保持所有Symfony bundle的程式碼一致性。看一眼AcmeDemoBundle,它包含了一個bundle最常見的某些元素:
Controller/
##裡面有該bundle的控制器(如`RandomController .php`)。 - DependencyInjection/
- Resources/config/
- Resources/views/
- Resources/public/
- Tests/