14

流行框架第 4 版的发布标志着项目结构发生了重大变化。包括官方文档中关于代码捆绑的以下说明(http://symfony.com/doc/current/bundles.html):

在 Symfony 4.0 之前的版本中,建议使用包来组织您自己的应用程序代码。不再建议这样做,并且捆绑包只能用于在多个应用程序之间共享代码和功能。

在第 2 版和第 3 版中,捆绑包执行了两项主要任务。1)如果开发人员或他们不同项目中的一组开发人员使用了一个大的重复功能,则可以将其以单独的捆绑包中取出并从项目转移到项目中。这种使用的一个很好的例子是任何项目中的用户系统。它包括用户模型、角色模型、权限模型(可能还有其他模型)、实体控制器,以及用于登录应用程序、退出应用程序的控制器(安全策略可能同时不同)和视图模板。另一个很好的例子是管理面板,其基础是相同的。2) Symfony 从逻辑的角度来看,在不同的目录中采用了单独的功能,因此,通过捆绑来命名空间。例如,在我过去的一个项目中,我划分了空间:用户管理系统、应用游戏化(社交网络目标)、合作伙伴空间、地理环境(用于处理地图和通过 IP 定义城市)、支付交易环境。如下。 Symfony[2-3] 项目结构

在我的下一个项目中,我不想使用 Symfony4 以外的任何东西来遵循框架的最佳实践来实现其新功能。如果官方文档不再坚持创建bundle,我该如何组织逻辑独立代码在不同区域的分离???如果模型的所有类都存储在同一个目录中,这会造成混乱并增加在大型项目结构中查找所需文件的时间。这同样适用于模板和其他一切。当我使用一个功能时,我只有这个功能的下拉目录。

现在 Symfony 是否鼓励您自行决定定义类、模板等的结构?

4

4 回答 4

8

作为 Symfony 的新手并从 4.2 版开始,我遇到了与 @DeveloperMobile 相同的问题。

目录结构

这是我的目录结构,基于 Guide Symfony Best Practices Version 4.2的建议

该建议基本上是关于结构的:

  • 将所有Controllers放在/src/Controller中,按Subfolder划分
  • 不要使用捆绑包,按命名空间组织代码
  • 将资产、配置、测试、模板、翻译、var/cache 和 var/log 放入根文件夹
  • 在 /src 中组织您的业务逻辑
  • 使用自动装配来自动配置应用程序服务。
  • 使用依赖注入获取服务
  • 瘦控制器和胖模型

所以基本上它说:是的,您可以使用子文件夹在 /src 中组织您的代码,但是具有特定功能的代码,如控制器、实体、表单、存储库等应该在特定的目录中。

执行

root/
├─ assets/
├─ bin/
│  └─ console
├─ config/
└─ public/
│  └─ index.php
├─ src/
   ├─ Controller/
     ├─ DefaultController.php
     ├─ ...
     ├─ Api/
     │   ├─ ..
     │   └─ ..
     ├─ Backend/
     │   ├─ ..
     │   └─ ..
   ├─ Entity/
   ├─ Form/
   ├─ Repository/
   ├─ Twig/
   ├─ Utils/
   └─ Kernel.php
├─ tests/
├─ templates/
├─ translations/
├─ var/
│  ├─ cache/
│  └─ log/
└─ vendor/

最佳实践 Symfony 4.2

这是上面链接中所有建议的列表:

安装

  • 使用 Composer 和 Symfony Flex 创建和管理 Symfony 应用程序。
  • 使用 Symfony Skeleton 创建新的基于 Symfony 的项目。

结构

  • 不要创建任何包来组织您的应用程序逻辑。

    (Symfony 应用程序仍然可以使用第三方包(安装在 vendor/ 中)来添加功能,但是您应该使用 PHP 命名空间而不是包来组织您自己的代码。)

配置

  • 将与基础架构相关的配置选项定义为环境变量。在开发过程中,使用项目根目录下的 .env 和 .env.local 文件进行设置。

  • 在 .env 文件中定义所有应用程序的环境变量

  • 在 config/services.yaml 文件中定义应用行为相关的配置选项。
  • 使用常量来定义很少更改的配置选项。
  • 配置参数的名称应尽可能短,并应包含整个应用程序的通用前缀。

商业逻辑

对于大多数项目,您应该将所有代码存储在 src/ 目录中。在这里,您可以创建任何想要组织事物的目录:

  • 使用自动装配来自动配置应用程序服务。
  • 应用程序服务的 id 应该等于它们的类名,除非您为同一个类配置了多个服务(在这种情况下,使用蛇案例 id)。
  • 服务应尽可能私有。这将阻止您通过 $container->get() 访问该服务。相反,您将需要使用依赖注入。
  • 使用 YAML 格式配置您自己的服务。
  • 使用注解来定义 Doctrine 实体的映射信息。

控制器

  • 让你的控制器扩展 Symfony 提供的 AbstractController 基础控制器,并尽可能使用注解来配置路由、缓存和安全性。
  • 不要将 Action 后缀添加到控制器操作的方法中。
  • 不要使用@Template 注解来配置控制器使用的模板。- 不要使用 $this->get() 或 $this->container->get() 从容器中获取服务。相反,使用依赖注入。
  • 使用 ParamConverter 技巧在简单方便时自动查询 Doctrine 实体。

模板

  • 为您的模板使用 Twig 模板格式。
  • 将应用程序模板存储在项目根目录下的 templates/ 目录中。
  • 对目录和模板名称使用小写的snake_case。
  • 对模板名称中的部分模板使用带前缀的下划线。
  • 在 src/Twig/ 目录中定义你的 Twig 扩展。您的应用程序将自动检测并配置它们。

形式

  • 将您的表单定义为 PHP 类。
  • 将表单类型类放在 App\Form 命名空间中,除非您使用其他自定义表单类,如数据转换器。
  • 在模板中添加按钮,而不是在表单类或控制器中。
  • 不要在表单中定义验证约束,而是在表单映射到的对象上定义。

国际化

  • 将翻译文件存储在项目根目录的 translations/ 目录中。
  • 为您的翻译文件使用 XLIFF 格式。
  • 始终使用键而不是内容字符串进行翻译。

安全

  • 除非您有两个合法不同的身份验证系统和用户(例如,用于主站点的表单登录和仅用于您的 API 的令牌系统),否则我们建议仅启用一个启用匿名密钥的防火墙条目。
  • 使用 bcrypt 编码器对用户密码进行哈希处理。
  • 定义自定义安全投票器以实施细粒度限制。

网络资产

  • 将资产存储在项目根目录的 assets/ 目录中。
  • 使用 Webpack Encore 编译、组合和最小化 Web 资产。

测试

  • 定义至少检查您的应用程序页面是否成功加载的功能测试。
  • 硬编码功能测试中使用的 URL,而不是使用 URL 生成器。
于 2019-04-06T10:18:33.093 回答
2

正如他们所说(source),您定义自己的结构,不建议重构所有实际应用程序

我们的建议是合理而明确的:您可以将这些最佳实践用于新应用程序,但您不应重构现有应用程序以符合这些最佳实践。

我希望你得到你的答案:)

于 2019-04-05T12:01:10.813 回答
0

正如@Nelson 所说,无需重构您当前的应用程序。

如果是新项目的话,基本上可以随心所欲。

例如,您可以像这样制作控制器

src
   - Controller
      - Bundle1 //Bundle is not the right word here, it's just to say you can separate your code in independents parts like this
      - Bundle2

逻辑类、模型(实体/文档)等也是如此。

您只需更改services.yaml文件以指示您的控制器在哪里,并定义您在哪些文件夹中拥有服务(可注入类)等。

你基本上可以自由地做任何你想做的事情,即使建议按照他们的 Demo App ( src/controller/*,src/Form/*等)

这个问题很老,我希望它仍然会帮助你。

于 2019-04-05T14:40:27.887 回答
-1

每个大型项目都应该分为后端、前端和api或服务,以及它们之间格式良好的变量键、错误码键和缓存键控制,因此每个项目都应该有自己的依赖关系,从而减少维护时间、开发时间、 ETC ...

backend.mysite.com

www.mysite (frontend)

api.mysite.com
于 2019-04-02T21:25:46.497 回答