新方法
自从我写了这个答案几个月后,我的方法发生了变化,所以我将它与社区分享。这个答案仍然很受欢迎,并且可以引导新手采用我认为不再是最好的方法。所以...
现在我只有 一个 应用程序特定包,我称之为AppBundle。旧方法存在一些问题,以下是其中的一些:
-
创建很多包很乏味。你必须为每个新包创建一个包类和一堆标准文件夹,然后激活它并注册它的路由和 DI 等等。 p>
-
不必要的核心决策过程。 有时您只是无法确定特定事物属于哪个捆绑包,因为它被多个捆绑包使用。在你花了半天时间,最终做出艰难的决定后,你会发现在几天或几周后,你将无法立即确定该放在哪个包裹中——因为大多数时候这个决定不是基于纯粹的逻辑,你必须根据抛硬币或任何你用来带来更高权力寻求帮助的方式来选择。
我过去曾建议将CommonBundle 用于常见的东西,但这样做你将不得不做很多不必要的重构,将一个东西移入和移出CommonBundle,这取决于以后有多少或几个包会使用那个东西.
-
无论如何,特定于应用程序的捆绑包是相互依赖的。当人们第一次遇到捆绑包的想法时,他们脑海中的主要想法之一就是“耶!我会给我一堆可重复使用的捆绑包!”这个想法很棒,我不反对。问题是 app specific bundles 无论如何都不是可重用的——它们是相互依赖的。忘记在这种情况下的重用。
-
不知道在哪里放置Behat 功能和步骤定义。 这个问题与前面的问题有关:您必须为每个捆绑包重复相同的无脑动作,然后做出核心决定。
当我开始编写 Behat 功能时,我只是无法决定将大量功能和步骤定义放在哪里,因为它们一次属于多个包。将它们放入 CommonBundle 似乎更糟糕,因为这是我在其中寻找这些东西的最后一个包。所以,我最终为此创建了 FeatureBundle。
切换到单个捆绑包解决了所有这些问题。
我还看到有些人为所有实体提供单独的捆绑包。我也不喜欢这种方法,实际上suggest keeping entities and other non Symfony2 specific stuff out of the bundles。
再次注意,这种新方法适用于应用程序特定包。官方文档和其他地方充满了关于如何构建旨在与他人共享并在众多项目中重用的捆绑包的很好的建议。 I write bundles of this type 也是。但是,经过数月的 Symfony2 项目工作后,我发现用于重用的包和特定于应用程序的包之间存在差异——一种方法并不适合所有。
当然,当您在特定应用的捆绑包中看到可重复使用的内容时,只需将其提取出来,放入单独的存储库并作为供应商安装即可。
此外,我发现自己更积极地使用子命名空间作为对包进行逻辑分区的一种方式——而不是为此创建一堆包并经历所有这些麻烦。
旧方法
没有硬性规定或灵丹妙药,但我会分享我的做事方法——也许它会给你一两个见解。
首先,我没有像FrontendBundle 和BackendBundle 这样的包罗万象的包。相反,我的包同时具有前端和后端控制器、视图等。因此,如果我从 UserBundle 中剥离除控制器和视图之外的所有内容,其结构将如下所示:
UserBundle
├── Controller
│ ├── Admin
│ │ └── UserController.php
│ └── UserController.php
├── Resources
│ └── views
│ ├── Admin
│ │ └── User
│ │ ├── add.html.twig
│ │ ├── delete.html.twig
│ │ ├── edit.html.twig
│ │ ├── form.html.twig
│ │ └── index.html.twig
│ └── User
│ ├── edit.html.twig
│ ├── sign-in.html.twig
│ ├── sign-up.html.twig
│ └── view.html.twig
└── UserBundle.php
其次,我有 CommonBundle 用于多个捆绑包共享的内容:
CommonBundle
├── Resources
│ ├── public
│ │ ├── css
│ │ │ ├── admin.css
│ │ │ ├── common.css
│ │ │ └── public.css
│ │ └── img
│ │ ├── add.png
│ │ ├── delete.png
│ │ ├── edit.png
│ │ ├── error.png
│ │ ├── return.png
│ │ ├── success.png
│ │ └── upload.png
│ └── views
│ ├── Admin
│ │ └── layout.html.twig
│ └── layout.html.twig
└── CommonBundle.php
我的app/Resources/views/base.html.twig 几乎与 Symfony 标准发行版中的一样:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>{{ block('title') | striptags | raw }}</title>
{% block stylesheets %}{% endblock %}
</head>
<body>
{% block body %}{% endblock %}
{% block javascripts %}{% endblock %}
</body>
</html>
CommonBundle/Resources/views/layout.html 和 CommonBundle/Resources/views/Admin/layout.html 都扩展了 app/Resources/views/base.html.twig。其他包的模板扩展了这两种布局之一,具体取决于它们是用于前端还是后端。基本上,这就是我使用Three-level Inheritance approach 的方式。
所以,我会将您的日期显示放入CommonBundle。根据其复杂性,它可能只是一个模板、macro 或 Twig extension。
分页是一个常见问题,因此我建议您使用existing bundles 之一,而不是重新发明轮子——当然,如果它们满足您的需求的话。
是的,没有控制器或视图等的捆绑包是完全可以的。