Bundle是一个有着良好定义结构的目录,它可以包含包括类、控制器和Web资源在内的任何东西。尽管Bundle非常灵活,但如果你想发布它的话,你还是应该遵循一些惯例:

Bundle名

Bundle还是一个PHP名称空间。该名称空间必须遵循PHP5.3名称空间和类名的技术互操作性标准:它由供应商段开始,后面接着0或更多的类别段,结束是名称空间的简称,必须以Bundle后缀结束。

名称空间在你向它添加一个Bundle类之后就变成一个Bundle。Bundle的类名必须遵循以下几个简单的规则:

  • 只能用字母数字和下划线;
  • 使用驼峰命名法;
  • 使用描述性的缩写名(不多于2个单词);
  • 名称的前缀并列供应商(或可选的类别名称空间);
  • 名称的后缀是Bundle。

这里有一些有效的Bundle名称空间和类名:

名称空间 Bundle类名
Acme\Bundle\BlogBundle AcmeBlogBundle
Acme\Bundle\Social\BlogBundle AcmeSocialBlogBundle
Acme\BlogBundle AcmeBlogBundle

根据约定,Bundle类的getName()方法应该返回类名。

如果你把你的Bundle公开,你必须要使用Bundle的类名做为库名(如要使用AcmeBlogBundle而非BlogBundle)。

Symfony2核心Bundle没有使用Bundle类的前缀Symfony,而总是添加Bundle的子命名空间;如FrameworkBundle

目录结构

HelloBundle的Bundle基本目录结构必须看上去如下所示:

  1. XXX/... 
  2.     HelloBundle/ 
  3.         HelloBundle.php 
  4.         Controller/ 
  5.         Resources/ 
  6.             meta/ 
  7.                 LICENSE 
  8.             config/ 
  9.             doc/ 
  10.                 index.rst 
  11.             translations/ 
  12.             views/ 
  13.             public/ 
  14.         Tests/ 

XXX目录(ies) 反映了Bundle的名称空间结构。

下列文件是强制的:

  • HelloBundle.php;
  • Resources/meta/LICENSE: 代码的完整许可;
  • Resources/doc/index.rst: 文档的根文件

这些约定确保自动工具可以根据这个缺省结构工作。

子目录的深度对于最常用的类和文件来说应该保持最小(最大2层)。更大的层可以用于那些非策略性、很少使用的文件。

Bundle目录是只读的,如果你需要写临时文件,可以将它们保存在应用程序的cache/或log/目录中。工具可以在Bundle目录结构中生成文件,但仅当生成的文件是库的一部分时。

下面的类和文件有着特定位置:

类型 目录
控制器 Controller/
翻译文件 Resources/translations/
模板 Resources/views/
单元和功能测试 Tests/
Web资源 Resources/public/
配置 Resources/config/
命令 Command/

Bundle目录结构被用于名称空间的层级。例如,HelloController控制器被保存在Bundle/HelloBundle/Controller/HelloController.php,因此完整的类名是 Bundle\HelloBundle\Controller\HelloController。

所有类和文件必须遵循Symfony2代码标准

一些类名应该清晰明了并且尽可能短,象Commands、Helpers、Listeners和 Controllers。

连接事件调试器的类名,其后缀应该是Listener。

异常类应该使用Exception子名称空间保存。

供应商

Bundle不得内嵌第三方PHP库。这个有赖于标准的Symfony2自动加载。

Bundle不应该内嵌JavaScript、CSS或任何其它语言编用的第三方库。

测试

Bundle应该自带一个用PHPUnit编写的测试套件,并保存在Test/目录下。测试应该遵循下列原则:

  • 测试套件必须可执行的,它可以在样例应用程序中通过简单PHPUnit命令运行;
  • 功能测试应该只用于测试响应输出和一些个人信息(如果你有的话);
  • 代码应该至少覆盖95%的代码库。

测试套件不必包含AllTests.php脚本,但必须依赖phpunit.xml.dist文件的存在。

文档

所有的类和函数都必须自带完整的PHPDoc。

广泛的文档(Extensive documentation)也应该在Resources/doc/目录中用reStructuredText格式提供;Resources/doc/index.rst是唯一的强制文件。

控制器

按照惯例,控制器在Bundle中就意味着它被分发给其它人时不能继承Controller基本类。它们可以实现ContainerAwareInterface或继承ContainerAware来代替。

如果你有看过Controller方法,你将明白它们只是设计良好的快捷方式,以便减小学习曲线。

模板

如果Bundle提供模板,它必须使用Twig。Bundle不必提供主布局,除非它要提供一个完整工作的应用程序。

模板文件

如果Bundle提供消息翻译,它们必须在XLIFF格式中定义;域名应该在Bundle名之后(bundle.hello)。

Bundle不得覆写其它Bundle中已存在的消息。

配置

为了提供更大的灵活性,Bundle可以通过Symfony2内建机制提供可配置设置。

简单的配置设置有赖于Symfony2配置中的缺省参数条目。Symfony2参数是简单的键/值对;值是任何有效的PHP值。每个参数名应该以使用下划线的小写Bundle缩写名开始(如:acme_hello对应AcmeHelloBundle或acme_social_blog对应Acme\Social\BlogBundle),尽管这只是最佳实践的建议。参数名的其它部分将使用句号(.)来分开不同的部分(如:acme_hello.email.form)。

最终用户可以在任何配置文件中为其提供值:

  1. # app/config/config.yml 
  2. parameters: 
  3.     acme_hello.email.from: fabien@example.com 

从容器里检索你代码中的配置参数:

  1. $container->getParameter('acme_hello.email.from'); 

尽管这种机制非常简单,但还是强烈鼓励你使用在食谱(cookbook)中描述的语义配置。