Symfony2概念问题:一般捆绑与特定捆绑

Nan*_*com 36 php bundle symfony

编辑:Symfony最佳实践回答了我的大部分问题.

我有几个关于我的Symfony2应用程序的问题.

它将有一个前端和后端,并且它们将使用一些公共代码(例如日期显示器,分页器,经常使用的一些模板等).

所以,我创建了一个FrontendBundle和一个BackendBundle,每个都包含例如它们各自的布局.第一个问题:为前端和后端创建捆绑包是不是很好的做法,这些捆绑包是甚至没有控制器的"通用"捆绑包?

第二个问题:我在食谱上读到我不应该将我的布局放在捆绑包中,而是放在app/Resources/views /目录中.我已经有了一个base.html.twig文件,我想知道是否应该将我的布局放在那里,比如frontend_layout.html.twig文件?

我创建了一个名为RootBundle的包,它将包含我的应用程序在前端和后端需要的所有内容.这是一个好的做法吗?或者我应该为每个提议的功能创建一个专用的捆绑包,例如PaginatorBundle,DateDisplayerBundle等等?听起来很奇怪,我有一个"杂项"捆绑包含我不知道放在哪里的所有内容.你是怎样做的?

Eln*_*mov 79

新方法

自从我写这个答案几个月后,我的方法发生了变化,所以我正在与社区分享.这个答案仍然非常受欢迎,并且可以引导新手采用我认为不再是最好的方法.所以...

现在我只有一个 特定于应用程序的包,我称之为AppBundle.旧方法存在一些问题,其中一些是:

  • 创建大量捆绑包很繁琐.您必须为每个新捆绑包创建捆绑类和一堆标准文件夹,然后激活它并注册其路由和DI等等.

  • 不必要的核心决策过程.有时您无法确定特定事物属于哪个捆绑包,因为它被多个捆绑包使用.在你花了半天时间并最终决定放置它的位置之后,你会发现在几天或几周内你将无法立即告诉哪个捆绑包看起来那个东西 - 因为大多数时候决定不是基于纯粹的逻辑,你必须选择基于硬币投掷或任何你用来提供更高权力的方法来帮助.

    我建议CommonBundle过去使用常见的东西,但这样做你必须做很多不必要的重构,CommonBundle根据有多少或几个捆绑包将来使用那个东西来移动东西.

  • 无论如何,应用程序特定的捆绑包是相互依赖的.当人们第一次遇到捆绑的想法时,他们心中想到的一个主要想法是"耶!我会给我一堆可重复使用的捆绑包!"这个想法太棒了,我没有反对它; 问题是应用程序特定的捆绑包无论如何都不是可重用的 - 它们是相互依赖的.在这种情况下忘记重用.

  • 不知道在哪里放置Behat功能和步骤定义.这个问题与之前的问题有关:你必须为每个束重复相同的无脑动作,然后做出硬核决定.

    当我开始编写Behat功能时,我无法决定在哪里放置大量功能和步骤定义,因为它们一次属于多个捆绑包.把它们放进去CommonBundle似乎更糟糕,因为这是我想要找到的最后一个包.所以,我最终FeatureBundle为此创造了.

切换到单个捆绑解决了所有这些问题.

我也看到有些人为所有实体都有一个单独的捆绑包.我不喜欢这种方法,并且实际建议将实体和其他非Symfony2特定的东西保留在捆绑包中.

请再次注意,此新方法适用于特定应用程序的捆绑包.官方文档和其他地方对于如何构建旨在与他人共享并在众多项目中重用的捆绑包充满了很好的建议.我也写这种类型的捆绑包.但是我在Symfony2项目工作数月之后发现的是,用于重用的捆绑包与特定应用程序捆绑包之间存在差异 - 一种方法并不适合所有方法.

当然,当您在特定应用程序包中看到可重用的东西时,只需将其解压缩,将其放在单独的仓库中并作为供应商安装.

此外,我发现自己更频繁地使用子名称空间作为一种逻辑分区的方法 - 而不是为此创建一堆捆绑并经历所有这些麻烦.

旧方法

没有严格的规则或银子弹,但我会分享我做事的方法 - 也许它会给你一两个洞察力.

首先,我没有这两个包罗万象捆状FrontendBundleBackendBundle.相反,我的bundle有前端和后端控制器,视图等.所以,如果我从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
Run Code Online (Sandbox Code Playgroud)

其次,我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
Run Code Online (Sandbox Code Playgroud)

app/Resources/views/base.html.twig几乎和Symfony Standard发行版一样:

<!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>
Run Code Online (Sandbox Code Playgroud)

两者CommonBundle/Resources/views/layout.htmlCommonBundle/Resources/views/Admin/layout.html延伸app/Resources/views/base.html.twig.其他bundle的模板扩展了这两种布局中的一种,具体取决于它们是用于前端还是后端.基本上,这就是我使用三级继承方法的方法.

所以,我会把你的日期显示器放进去CommonBundle.根据其复杂性,它可以只是模板,Twig 扩展.

分页是一个常见的问题,所以我建议你使用现有的 一个捆绑而不是重新发明轮子 - 当然,如果它们满足你的需求.

是的,拥有没有控制器或视图等的捆绑包是完全可以的.

  • 我认为`CommonBundle`的另一个好名字可能是`<在这里插入您的项目名称> Bundle`,因为它应该包含特定于您的项目的所有内容,并且您认为您不会在任何地方重复使用. (6认同)
  • 在阅读了更新后的方法之后,我不知道是否赞成旧的还是新的:D (5认同)
  • 我非常喜欢你的方法,但我更喜欢为admin和main设置不同的bundle(在不同的bundle中有不同的控制器和视图).主要原因是管理部分通常依赖于主要(服务,实体等),但主要不依赖于管理部分.主捆绑中的代码少:) (3认同)