跳到内容

约定

编辑此页

编码标准文档描述了 Symfony 项目以及内部和第三方扩展包的编码标准。本文档描述了核心框架中使用的编码标准和约定,以使其更一致和可预测。我们鼓励你在自己的代码中遵循它们,但这并不是强制的。

方法命名

当一个对象与相关的“事物”(对象、参数等)有“主要”多对多关系时,方法名称会被规范化

  • get()
  • set()
  • has()
  • all()
  • replace()
  • remove()
  • clear()
  • isEmpty()
  • add()
  • register()
  • count()
  • keys()

只有当明确存在主要关系时,才允许使用这些方法

  • 一个 CookieJar 拥有多个 Cookie 对象;
  • 一个服务 Container 拥有多个服务和多个参数(由于服务是主要关系,因此命名约定用于此关系);
  • 一个控制台 Input 拥有多个参数和多个选项。没有“主要”关系,因此命名约定不适用。

对于约定不适用的多对多关系,必须使用以下方法代替(其中 XXX 是相关事物的名称)

主要关系 其他关系
get() getXXX()
set() setXXX()
不适用 replaceXXX()
has() hasXXX()
all() getXXXs()
replace() setXXXs()
remove() removeXXX()
clear() clearXXX()
isEmpty() isEmptyXXX()
add() addXXX()
register() registerXXX()
count() countXXX()
keys() 不适用

注意

虽然 setXXX()replaceXXX() 非常相似,但有一个明显的区别:setXXX() 可能会替换或向关系中添加新元素。replaceXXX() 则相反,它不能添加新元素。如果将无法识别的键传递给 replaceXXX(),则必须抛出异常。

编写 CHANGELOG 条目

在次要版本中添加新功能或弃用现有行为时,应在相关的 CHANGELOG 中添加条目。

新功能和弃用必须在名为 CHANGELOG.md 的文件中描述,该文件应位于修改后的组件、Bridge 或 Bundle 的根目录中。

该文件必须使用 Markdown 语法编写,并遵循以下约定

  • 主标题始终为 CHANGELOG
  • 每个条目都必须作为列表元素添加到次要版本部分(如 5.3);
  • 不允许使用三级标题;
  • 消息应遵循 提交消息约定:应简短,首字母大写,末尾不加句点,使用祈使动词开头;
  • 新条目必须添加到列表的顶部。

这是一个完整的示例供参考

1
2
3
4
5
6
7
CHANGELOG
=========

5.3
---

 * Add `MagicConfig` that allows configuring things

注意

symfony/symfony 根目录下的主 CHANGELOG-* 文件在准备发布时自动生成,绝不应手动修改。

弃用代码

有时,框架中的某些类和/或方法会被弃用;当由于向后兼容性问题而无法更改功能实现时,但我们仍然希望提出“更好”的替代方案时,就会发生这种情况。在这种情况下,旧的实现可以被弃用

弃用只能在受影响组件(或 bundle、bridge 或 contract)的下一个次要版本中引入。如果它们是关键的,则可以例外地在以前支持的版本中引入。

新的类(或接口,或 trait)不能作为已弃用引入,也不能包含已弃用的方法。

新的方法不能作为已弃用引入。

通过向相关的类、方法、属性等添加 @deprecated PHPDoc,将功能标记为已弃用。

1
2
3
/**
 * @deprecated since Symfony 5.1.
 */

弃用消息必须指示功能被弃用的版本,并在可能的情况下,说明如何替换它

1
2
3
/**
 * @deprecated since Symfony 5.1, use Replacement instead.
 */

当替换项与已弃用的类在不同的命名空间中时,必须使用其 FQCN

1
2
3
/**
 * @deprecated since Symfony 5.1, use A\B\Replacement instead.
 */

还必须触发弃用,以帮助人们进行迁移(需要 symfony/deprecation-contracts 包)

1
trigger_deprecation('symfony/package-name', '5.1', 'The "%s" class is deprecated, use "%s" instead.', Deprecated::class, Replacement::class);

当弃用整个类时,trigger_deprecation() 调用应放在 use 声明之后,如 ServiceRouterLoader 中的示例所示

1
2
3
4
5
6
7
8
9
10
namespace Symfony\Component\Routing\Loader\DependencyInjection;

use Symfony\Component\Routing\Loader\ContainerLoader;

trigger_deprecation('symfony/routing', '4.4', 'The "%s" class is deprecated, use "%s" instead.', ServiceRouterLoader::class, ContainerLoader::class);

/**
 * @deprecated since Symfony 4.4, use Symfony\Component\Routing\Loader\ContainerLoader instead.
 */
class ServiceRouterLoader extends ObjectRouteLoader

必须将弃用添加到受影响组件的 CHANGELOG.md 文件中

1
2
3
4
4.4
---

* Deprecate the `Deprecated` class, use `Replacement` instead

它还必须添加到目标次要版本的 UPGRADE.md 文件中(在我们的示例中为 UPGRADE-4.4.md

1
2
3
4
DependencyInjection
-------------------

 * Deprecate the `Deprecated` class, use `Replacement` instead

最后,其后果必须添加到下一个主要版本的 UPGRADE.md 文件中(在我们的示例中为 UPGRADE-5.0.md

1
2
3
4
DependencyInjection
-------------------

 * Remove the `Deprecated` class, use `Replacement` instead

所有这些任务都是强制性的,必须在同一个 pull request 中完成。

移除已弃用的代码

移除已弃用的代码只能每两年进行一次,在受影响组件的下一个主要版本 (6.0 分支、7.0 分支等) 中进行。

移除已弃用的代码时,必须将弃用的后果添加到受影响组件的 CHANGELOG.md 文件中

1
2
3
4
5.0
---

 * Remove the `Deprecated` class, use `Replacement` instead

此任务是强制性的,必须在同一个 pull request 中完成。

命名命令和选项

命令及其选项的命名和描述应使用英语祈使语气(即 'run' 而不是 'runs','list' 而不是 'lists')。使用祈使语气简洁明了,并与类似的命令行界面(例如 Unix man pages)保持一致。

这项工作,包括代码示例,根据 Creative Commons BY-SA 3.0 许可协议获得许可。
目录
    版本