Symfony 4 中大型项目的代码分离最佳实践是什么?

What will be the best practice of code separating for a large projects in Symfony4?

流行框架第 4 版的发布标志着项目结构的重大变化。包括官方文档在内,关于代码捆绑的注释如下(http://symfony.com/doc/current/bundles.html):

In Symfony versions prior to 4.0, it was recommended to organize your own application code using bundles. This is no longer recommended and bundles should only be used to share code and features between multiple applications.

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

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

现在Symfony是不是鼓励大家自行定义类的结构、模板之类的东西了?

每个大项目都应该拆分成后端,前端,和api或者服务,并且之间有一个格式良好的变量键,错误码键和缓存键控制,所以每个项目都应该 有自己的依赖,它减少了维护时间、开发时间等...

backend.mysite.com

www.mysite (frontend)

api.mysite.com

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

Our recommendation is sound and clear: you may use these best practices for new applications but you should not refactor your existing applications to comply with these best practices.

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

正如@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

同样适用于逻辑 类、模型 (Entity/Document) 等

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

你基本上可以自由地做任何你想做的事,即使建议遵循他们的演示应用程序(src/controller/*src/Form/* 等)

这个问题是老问题了,希望它仍然对你有帮助。

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

目录结构

这是我根据指南中的建议创建的目录结构 Symfony Best Practices 版本 4.2

推荐基本上说了结构:

  • 将所有控制器放入/src/Controller,除以子文件夹
  • 不要使用 Bundle,按命名空间组织代码
  • 将资产、配置、测试、模板、翻译、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

这是上面 Link 中所有推荐的列表:

安装

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

结构

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

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

配置

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

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

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

业务逻辑

对于大多数项目,您应该将所有代码存储在 src/ 目录中。在这里,您可以创建 无论您想组织什么目录:

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

控制器

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

模板

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

表格

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

国际化

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

安全

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

网络资产

  • 将您的资产存储在项目根目录下的 assets/ 目录中。
  • 使用 Webpack Encore 编译、合并和最小化网络资源。

测试

  • 定义至少检查您的应用程序页面是否成功加载的功能测试。
  • 硬编码功能测试中使用的 URL,而不是使用 URL 生成器。