关于 symfony-components
面向 Symfony 开发者的组件使用 Skill,指导按项目版本查找 API 文档,并提供常见组件的实践建议与易错点。
主要功能
- 01核实已安装的 Symfony 和 PHP 版本
- 02查找对应版本的 API 文档
- 03优先使用属性与自动装配
- 04提供组件默认实践建议
- 05提示长驻 Worker 的常见问题
- 06整理跨组件排查要点
适用场景
- 01为项目当前 Symfony 版本选择 API
- 02实现 Messenger 或 Cache 工作流
- 03检查 Worker 安全性与弃用项
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ krzysztofsurdy/ code-virtuoso --skill symfony-components安装后在 Claude Code 中输入/symfony-components确认已加载。
附带文件references/pitfalls.md
详细介绍
Symfony 组件
Symfony 每年发布两次次要版本,其 API 也会随之变化。本技能不会复述 API,而是告诉你如何确定当前使用的版本、从哪里获取该版本的准确 API、文档提供多种选项时应优先采用哪些默认做法,以及真实项目中反复出现哪些错误。
核心原则
| 原则 | 含义 |
|---|---|
| 先确认版本 | 在建议任何 API 之前,先读取已安装的版本。对“Symfony 7”的记忆往往已经过时。 |
| 文档优先于记忆 | 获取所需组件和版本对应的页面。不要凭记忆粘贴 API。 |
| 属性和自动装配 | 优先使用 PHP 属性和自动装配。只有属性无法表达时才使用 YAML 或 XML。 |
| 明确失败,长时间运行 | 代码必须能在长时间运行的工作进程中正常工作:不得泄漏状态,处理程序必须幂等。 |
| 零弃用 | 将弃用通知视为逐步收紧的标准。它们是升级到下一个主版本的路径。 |
第 1 步:查找已安装的版本
从 composer.lock 中读取,而不是看 composer.json 的约束(^7.2 说明不了多少)。
jq -r '.packages[] | select(.name|test("^symfony/(framework-bundle|http-kernel)$")) | .name+" "+.version' composer.lock
还要检查 composer.json 中的 php 约束和 CLI 版本。使用 6.4 或 7.4 的项目,需要的答案与使用 8.1 的项目不同:属性名称有所变更,功能陆续加入,一些 API 也在 8.0 中被移除。
版本矩阵
根据 https://symfony.com/releases 于 2026-10-21 核实。
| 分支 | 状态 | 最低 PHP 版本 | 支持结束时间 |
|---|---|---|---|
| 8.1 | 当前稳定版,非 LTS | 8.4 | 2027 年 1 月(错误修复和安全支持) |
| 8.2 | 开发中,计划于 2026 年 11 月发布 | 8.4 | 2027 年 7 月 |
| 7.4 | LTS | 8.2 | 错误修复:2028 年 11 月;安全支持:2029 年 11 月 |
| 6.4 | LTS | 8.1 | 错误修复:2026 年 11 月;安全支持:2027 年 11 月 |
| 8.0 | 已停止维护 | 8.4 | 于 2026 年 7 月结束 |
| 5.4 | 仅提供安全修复 | 7.2.5 | 2029 年 2 月 |
经验法则:
- 主版本的次要版本不是 LTS,生命周期约为 8 个月。LTS 版本以
.4结尾。按此规律,下一个 LTS 版本是 8.4(发布页面尚未确认)。 - 从 7.4 升级到 8.x,意味着必须先升级到 PHP 8.4。对于使用 7.4 或 6.4 的项目,不要编写仅适用于 8.x 的语法。
- 不要将“PHP 8.3+”或“Symfony 7.x”作为基准版本。应使用项目自身的约束。
第 2 步:通过 docs-lookup 获取 API 详情
使用 docs-lookup 技能执行获取流程。如果未安装该技能,请使用遵循相同规则的任意文档工具:解析库,一次只查询一个概念,并检查结果中的版本说明。
| 来源 | Context7 ID | 用途 |
|---|---|---|
| 当前文档站点 | /websites/symfony_doc_current | 最新稳定版的行为 |
| 文档,固定分支 | /symfony/symfony-docs/__branch__X.Y | 使用特定版本的项目 |
| 文档,7.4 站点 | /websites/symfony_doc_7_4 | 使用 7.4 的项目 |
| 文档,广泛索引 | /websites/symfony | 其他来源找不到主题时的备用选项 |
截至 2026-10-21 存在的固定分支:6.4、7.4、8.0。当时没有 8.1 分支,因此 8.1 应使用当前文档 ID。源代码仓库中的文档也可在 /symfony/symfony 找到(当时的标签为 v8.0.0、v7.4.3)。
已知陷阱:
- 当前文档 ID 返回的结果可能包含为 7.4 或更早版本编写的页面。查找“引入于”和“弃用于”说明,并与已安装版本进行比较。
- 在 8.1 上可运行的代码片段,可能会使用项目的 PHP 无法运行的语法(例如,不加括号的
new链式调用需要 PHP 8.4)。 - 如果工具找不到匹配项,请改用特定分支的
https://symfony.com/doc/X.Y/。
每次只查询一个组件和一个概念,例如“Messenger 重试策略和失败传输”,不要查询“messenger 和 cache 和 forms”。
主张明确的默认方案
文档列出了各种选项。用户没有另行说明时,就采用以下方案。
- 优先使用 Attributes,而非 YAML/XML 配置路由、命令(
#[AsCommand])、处理器(#[AsMessageHandler])、监听器(#[AsEventListener])、验证和序列化分组。config/packages和服务参数仍使用 YAML。 - 应用服务使用自动装配和自动配置。仅当服务需要标量参数、接口的特定实现或非默认标签时,才手动注册。
- 使用构造函数注入,服务设为私有,应用代码中不使用
ContainerInterface。需要一组服务时,注入服务定位器或使用#[AutowireIterator]。 - 工作流组件:默认使用状态机。 仅当对象必须同时处于多个位置时,才使用完整工作流。位置由 PHP 枚举支持。
- 缓存:使用 Cache Contracts(
$cache->get($key, $callback)),而非原始 PSR-6。它可以防止缓存击穿并提前过期。务必设置 TTL,按依赖项添加标签,并通过标签失效。 - **Messenger:**处理器必须幂等(至少投递一次),消息携带标识符而非实体;命令总线启用
doctrine_transaction中间件,配置失败传输,并限制工作进程(--time-limit、--memory-limit)。 - **表单
CollectionType:**需要设置allow_add、allow_delete、by_reference: false,并在模型中同时提供添加器和移除器。没有移除器时,已移除的行会重新出现。 - **Validator:**使用 Attributes 将约束放在模型上,使用验证组处理特定上下文的规则;自定义验证器遇到
null和空值时应提前返回(交由NotBlank和NotNull处理)。 - **Serializer:**通过序列化分组或 DTO 暴露 API 输出,绝不直接序列化完整的 Doctrine 实体。显式将实体映射到 DTO(此处可使用 ObjectMapper 组件)。
- **Security:**使用投票器进行对象级授权,
access_control仅用于粗粒度 URL 规则,控制器上使用#[IsGranted]。不要到处散布in_array('ROLE_X', $user->getRoles())检查。 - **事件:**使用自定义事件类,以类名作为事件名称,监听器保持精简且无状态。将耗时工作从
kernel.response移到kernel.terminate或 Messenger。 - **时间:**注入
ClockInterface,领域代码中绝不调用new \DateTimeImmutable()或time()。测试中使用MockClock。 - **锁:**务必设置 TTL,长时间运行时刷新锁,并选择所有服务器共享的存储(不要在不同主机之间使用
flock)。 - **进程:**以数组形式传递命令,而不是 shell 字符串。仅在输入可信且已转义时使用
fromShellCommandline()。 - **标识符:**主键优先使用 UUIDv7 或 ULID,而非 UUIDv4,因为按时间排序的 ID 能让索引更紧凑。
- **Bundles:**新建 Bundle 时扩展
AbstractBundle。为每个配置选项提供默认值,移除选项前先将其弃用。
常见注意事项
- Doctrine 懒加载导致的 N+1 查询。 循环访问关联关系时,每行都会触发一次查询。使用联接进行提取(
addSelect),借助分析器统计查询数量,并使用符合实际规模的数据进行测试。 - 长时间运行的 Worker 泄漏。 Messenger、Swoole、RoadRunner 和 FrankenPHP Worker 会让内核保持运行。状态化服务需要实现
ResetInterface(或使用kernel.reset标签),实体管理器必须在处理消息之间清理,并且静态缓存不得无限增长。部署时使用messenger:stop-workers重启 Worker。 - 环境变量处理器。
%env(int:PORT)%等变量会在运行时解析,但容器参数会在编译时解析。编译时构建的内容中不要使用环境变量值(编译器传递、Bundle 扩展逻辑)。使用处理器转换类型,而不是在代码中转换。 - 弃用项逐步累积。 开启弃用项报告并使用基线文件运行测试;当弃用项数量增加时,让 CI 失败。在升级到下一个大版本之前,先在当前大版本的最后一个次要版本中清除弃用项。
- 开发环境与生产环境不一致。 调试模式会掩盖
cache:clear --env=prod和lint:container能发现的容器错误。在 CI 中同时运行这两项命令。 - 在内核监听器中忘记使用
isMainRequest(),导致子请求重复执行逻辑。 - 在处理器中捕获
\Throwable并直接返回,这会让 Messenger 将消息视为处理成功。应让异常继续传播,或按需抛出UnrecoverableMessageHandlingException。
按组件整理的更多说明及原因见:references/pitfalls.md。使用 Messenger、Form、Cache、Lock、Workflow 或 Validator 时请阅读。
组件索引
仅供参考。请通过 docs-lookup 获取 API。
HTTP 和运行时: HttpFoundation(请求和响应对象)、HttpKernel(请求到响应的管道和内核事件)、Routing(URL 匹配和生成)、Runtime(解耦引导、长运行服务器)、PSR-7 Bridge(转换为 PSR-7 格式及从 PSR-7 格式转换)、HttpClient(同步和异步 HTTP 调用、重试、模拟客户端)、BrowserKit 和 DomCrawler 和 CssSelector(模拟浏览器并查询 HTML)、Mime 和 Mailer(构建和发送电子邮件)、Asset 和 AssetMapper(资源 URL、无需构建的前端资源)。
消息传递和时间: Messenger(消息总线、传输、工作进程、重试)、Scheduler(定期消息)、Webhook 和 RemoteEvent(接收第三方回调)、Notifier(短信、聊天、推送)、Clock(可测试的时间,DatePoint)、RateLimiter(令牌桶和窗口限制,8.1 中支持基于属性的配置)。
容器和配置: DependencyInjection(容器、自动装配、编译器传递)、Config(配置树、Bundle 选项)、Contracts(适用于缓存、事件、HTTP、翻译的框架无关接口)、EventDispatcher(监听器和订阅者)、ExpressionLanguage(安全的表达式沙箱)、Yaml(解析和转储)、OptionsResolver(经过验证的选项数组)。
数据和类型: Form(表单类型、数据转换器、集合)、Validator(约束和分组)、Serializer(对象转为数组/JSON/XML)、ObjectMapper(将一个对象映射到另一个对象,适用于 DTO)、JsonStreamer(低内存占用的 JSON 编码和解码)、JsonPath(RFC 9535 查询)、PropertyAccess(按路径读取和写入)、PropertyInfo 和 TypeInfo(类型和元数据提取)、Uid(UUID 和 ULID)、Intl(区域设置数据)、Translation(消息和 ICU 格式)、HtmlSanitizer(对用户输入生成安全的 HTML)。
安全: Security(身份验证器、防火墙、投票器、访问控制、密码哈希)。
并发和系统: Cache(PSR-6 和 PSR-16 缓存池、标签、防击穿)、Lock(跨进程的排他锁)、Semaphore(有限的并发访问,8.1 中扩展了后端)、Process(运行外部命令)、Filesystem 和 Finder(文件操作和搜索)、Ldap(目录访问)。
控制台和工具: Console(命令、输入、输出、辅助工具)、Tui(全屏终端 UI,8.1 中新增)、VarDumper(易读的转储)、VarExporter(兼容 OPcache 的导出、惰性对象)、PHPUnit Bridge(在测试中报告弃用情况并模拟时间或 DNS)。
并非 Symfony 组件,但很常见: Twig(模板、Twig Bridge)、Doctrine ORM 和 DBAL(通过 DoctrineBundle 和 Doctrine bridge 集成,并与 Messenger 和 Validator 集成)。
快速检查清单
- 从
composer.lock和运行时读取已安装的 Symfony 和 PHP 版本。 - 编写代码前,先获取对应版本的 API。
- 优先使用属性、自动装配和构造函数注入。
- 检查长运行行为:状态重置、幂等性、限制。
- 启用弃用报告运行测试,并修复新出现的提示。
与其他技能集成
| 情况 | 推荐技能 |
|---|---|
| 获取最新的库文档 | docs-lookup |
| 在 Symfony 主版本或次版本之间迁移 | symfony-upgrade |
| 安全地更新软件包 | composer-dependencies |
| 使用 PHPUnit 编写测试 | testing |
| 审查授权或输入处理 | security |
| 查找查询问题 | performance |
| 设计分层和边界 | clean-architecture |