Bundle系統(tǒng)
bundle類似于其他軟件中的插件,但卻更好。關(guān)鍵區(qū)別在于:Symfony中的每一樣?xùn)|西都是bundle,包括框架核心功能,以及你編寫的程序代碼。bundle是Symfony體系中的一等公民。這就給了你一個彈性架構(gòu),既可以使用 第三方bundle 中的預(yù)建功能,也可以發(fā)布你自己的bundle。bundle可以讓你在自己的程序中挑選“開啟哪個功能”變得很容易,還能按你的方式來優(yōu)化之。
在本文中你可以學(xué)到bundle基礎(chǔ)知識,“最佳實(shí)踐”中有大章節(jié)專注于bundle的組織和最佳實(shí)踐。
一個bundle,就是一組結(jié)構(gòu)化的文件,存于一個“用于實(shí)現(xiàn)某個獨(dú)立功能”的目錄中。你可以創(chuàng)建一個BlogBundle,一個ForumBundle,或者是一個管理用戶的bundle(很多類似bundle已經(jīng)作為開源項目存在)。每個目錄都包含著關(guān)乎那個功能的所有東西,包括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
中所配置的自動加載器實(shí)現(xiàn))
創(chuàng)建一個Bundle ?
Symfony標(biāo)準(zhǔn)版內(nèi)置了超好用的命令,用來幫你創(chuàng)建全功能bundle。當(dāng)然,手動創(chuàng)建bundle也一樣容易。
為了展示一個簡單的bundle系統(tǒng),我們創(chuàng)建一個全新的AcmeTestBundle并開啟它。
Acme
部分只是個假名,實(shí)戰(zhàn)中應(yīng)被一些“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
)
這個空類就是你在創(chuàng)建全新bundle時,唯一需要的東西。盡管一般情況下確實(shí)是空的,但這個類格外強(qiáng)大,專門用于定制該bundle的各種行為。
現(xiàn)在你已經(jīng)創(chuàng)建了bundle,在AppKernel
類中開啟它:
// app/AppKernel.phppublic function registerBundles(){ $bundles = array( // ... // register your bundle / 注冊你的bundle new Acme\TestBundle\AcmeTestBundle(), ); // ... return $bundles;}
盡管目前啥也沒做,AcmeTestBundle已經(jīng)可以使用。
就這么簡單,Symfony也提供了命令行界面,用于生成一個基本的bundle骨架:
$ php bin/console generate:bundle --namespace=Acme/TestBundle
bundle骨架包括控制器、模板和路由資源等,而且都可以自定義。在后面的Symfony命令行工具小節(jié),你可以學(xué)到更多。
不管是創(chuàng)建新bundle還是使用第三方bundle,應(yīng)確保bundle被 registerBundles()
開啟。當(dāng)使用 generate:bundle
命令時,Symfony替你注冊完成了。
Bundle目錄結(jié)構(gòu) ?
bundle目錄是簡單而有彈性的。默認(rèn)條件下,bundle系統(tǒng)遵循著一組命名約定,以保持所有Symfony bundle的代碼一致性??匆谎跘cmeDemoBundle,它包括了一個bundle最常見的某些元素:
Controller/
- 里面有該bundle的控制器(如 `RandomController.php`)。
DependencyInjection/
- 里面有特定的Dependency Injection Extension類,用來導(dǎo)入服務(wù)配置信息,注冊compiler passes,以及更多內(nèi)容(這個目錄并非必需)。
Resources/config/
- 存放配置信息,包括路由配置(`routing.yml` 等)。
Resources/views/
- 存放模板。依控制器名字來組織子文件夾(如 `Hello/index.html.twig`)。
Resources/public/
- 存放web assets資源(圖片,css等),將通過硬拷貝或symlink方式導(dǎo)入到項目的 `web/` 目錄,通過console命令 `assets:install` 實(shí)現(xiàn)。
Tests/
- 存放本bundle的所有測試類。
一個bundle依其實(shí)現(xiàn)的功能而或小或大。它只包含你需要的文件,再無其他。
在你通讀中文指南的過程中,你將學(xué)到如何持久化對象到數(shù)據(jù)庫中,創(chuàng)建和驗證表單,為程序增加翻譯功能,編寫測試,以及更多內(nèi)容。所有這些,都是基于bundle而有自己的目錄和功能。