mcpField
S
symfony-components

symfony-components

github.com/krzysztofsurdy开发36108 次安装1 天前更新
代码仓库

关于 symfony-components

面向 Symfony 开发者的组件使用 Skill,指导按项目版本查找 API 文档,并提供常见组件的实践建议与易错点。

主要功能

  1. 01核实已安装的 Symfony 和 PHP 版本
  2. 02查找对应版本的 API 文档
  3. 03优先使用属性与自动装配
  4. 04提供组件默认实践建议
  5. 05提示长驻 Worker 的常见问题
  6. 06整理跨组件排查要点

适用场景

  1. 01为项目当前 Symfony 版本选择 API
  2. 02实现 Messenger 或 Cache 工作流
  3. 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当前稳定版,非 LTS8.42027 年 1 月(错误修复和安全支持)
8.2开发中,计划于 2026 年 11 月发布8.42027 年 7 月
7.4LTS8.2错误修复:2028 年 11 月;安全支持:2029 年 11 月
6.4LTS8.1错误修复:2026 年 11 月;安全支持:2027 年 11 月
8.0已停止维护8.4于 2026 年 7 月结束
5.4仅提供安全修复7.2.52029 年 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

评论

支持 Markdown