需将 security.yaml 中的 ‘%secret%’ 替换为 ‘%env(APP_SECRET)%’,确保 .env 含 APP_SECRET,删除旧 parameters 文件,并验证 kernel.secret 参数。

“You have requested a non-existent parameter ‘secret’”错误怎么修?
这个错误不是配置写错了,而是 Symfony 4.4 彻底移除了全局 secret 参数的自动注入机制。它现在只认 kernel.secret(由 APP_SECRET 环境变量驱动),但旧版 security.yaml 里还写着 remember_me: secret: '%secret%',框架一读就炸。
- 检查
config/packages/security.yaml,把所有'%secret%'替换成'%env(APP_SECRET)%' - 确保
.env文件里有APP_SECRET=……(长度建议 32 位以上) - 删除任何残留的
app/config/parameters.yml或parameters.php—— Symfony 4.4 不再从那里加载参数 - 运行
php bin/console debug:container --parameter=kernel.secret验证是否能正常输出
不改这里,cache:clear 和所有命令都会失败,哪怕 framework.yaml 里已经配好了 secret。
升级必须分步走:先框架核心,再 Bundle,最后自定义代码
Symfony 官方明确不支持跨 LTS 直升(比如 3.4 → 4.4),但也不强制你逐个小版本过(3.4→4.0→4.1→……→4.4)。实际可行路径是:3.4 → 4.0 → 4.4,每步只动最小范围。
- 第一步:只升级
symfony/framework-bundle和symfony/http-kernel到^4.0,其他保持^3.4 - 第二步:跑
php bin/console cache:clear和php bin/console debug:router,修复Kernel::registerBundles()返回类型、AppKernel类名变更等基础报错 - 第三步:升级
symfony/twig-bundle、symfony/orm-pack等官方 Bundle,注意doctrine/doctrine-bundle从 1.x 升到 2.x 时doctrine.dbal版本需同步匹配 - 最后才碰自定义代码:比如手动调用
$this->get('service')的地方,得改成构造器注入;ContainerAwareTrait全部删掉
跳过中间步骤直接全量 composer update,大概率会触发一堆冲突,比如 symfony/console 要求 PHP 7.1+,而你的 monolog-bundle 还卡在 3.x,根本拉不下来。
Flex 和 recipes 是帮手,不是自动完成器
Symfony 4 引入 Flex 后,很多配置会自动写进 config/packages/,看着省事,但容易掩盖问题。
- 运行
composer require symfony/flex后,先别急着composer update - 查看
composer.json里是否已加"extra": {"symfony": {"allow-contrib": false}},没加就补上,避免第三方 recipe 干扰 - 升级后检查
config/bundles.php,确认每个 bundle 的启用条件(如if (class_exists(……)))是否还成立 - Flex 自动生成的
config/packages/framework.yaml里可能含冗余项(比如form: true在没装symfony/form时会报错),要按需删
Flex 不会帮你改业务逻辑,也不会告诉你 doctrine:generate:entities 命令已在 4.0 废弃——它只管“配好”,不管“跑通”。
测试跑不过?先盯住 deprecation 警告和 Doctrine schema 变更
Symfony 3.4 到 4.4 的最大坑不在语法,而在隐性行为变化:
- 运行
php bin/console debug:deprecations,重点看ContainerAwareInterface、get()方法、getDoctrine()->getManager()的调用位置 - Doctrine ORM 升级到 2.6+ 后,
nullable=false字段默认不再生成NOT NULL约束,php bin/console doctrine:schema:update --dump-sql可能输出意外的ALTER TABLE - 表单验证规则里用的
@AssertNotBlank在 4.4 默认开启strict=true,空字符串会被当 null 处理,导致验证失败
没有足够功能测试的项目,升级等于盲拆炸弹。至少确保 phpunit 能跑通所有 Controller 和 Form 测试,否则上线后第一个 POST 请求就 500。
Flex recipe 自动加的 config/packages/dev/web_profiler.yaml 很方便,但它默认禁用生产环境 profiler —— 这个细节没人提,但一旦你在 prod 环境想查缓存命中率,就会发现 profiler 根本没加载。