Bundle系統


bundle類似於其他軟體中的插件,但更好。關鍵區別在於:Symfony中的每一樣東西都是bundle,包括框架核心功能,以及你寫的程式碼。 bundle是Symfony體系中的一等公民。這就給了你一個彈性架構,既可以使用 第三方bundle 中的預建功能,也可以發佈你自己的bundle。 bundle可以讓你在自己的程式中挑選「開啟哪個功能」變得容易,還能以你的方式來優化。

在本文中你可以學到bundle基礎知識,「最佳實踐」中有大章節專注於bundle的組織和最佳實踐。

一個bundle,就是一組結構化的文件,存於一個「用來實現某個獨立功能」的目錄中。你可以創建一個BlogBu​​ndle,一個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/
  • 裡面有特定的Dependency Injection Extension類,用來導入服務配置信息,註冊compiler passes,以及更多內容(這個目錄並非必需) 。
  • Resources/config/
  • 可存放設定訊息,包括路由配置(`routing.yml` 等)。
  • Resources/views/
  • #存放模板。依控制器名字來組織子資料夾(如 `Hello/index.html.twig`)。
  • Resources/public/
  • 可存放web assets資源(圖片,css等),將透過硬拷貝或symlink方式匯入到專案的`web/` 目錄,透過console指令`assets:install` 實作。
  • Tests/
  • 存放本bundle的所有測試類別。
一個bundle依其實現的功能而或小或大。它只包含你需要的文件,再無其他。

在你通讀中文指南的過程中,你將學到如何持久化物件到資料庫中,建立和驗證表單,為程式增加翻譯功能,編寫測試,以及更多內容。所有這些,都是基於bundle而有自己的目錄和功能。