Symfony 3.4 升级后需修正模板路径、表单实体绑定、事件分发器签名及标量参数注入:模板移至 app/Resources/views/ 并删 @Template;表单避免未持久化实体,改用 DTO 或显式配置;事件类改用 Symfony\Contracts\EventDispatcher\Event;标量参数须在 services.yml 中显式绑定。

doctrine:generate:crud 生成的模板路径错乱怎么办
升级后运行 doctrine:generate:crud,模板仍被写进 src/AppBundle/Resources/views/,但 Symfony 3.4 已要求所有模板统一放在 templates/(或旧项目中的 app/Resources/views/),否则渲染直接报错“Template not found”。
- 立刻把
src/AppBundle/Resources/views/下的整个目录剪切到app/Resources/views/,并重命名成对应控制器名(如AnamnesisController→anamnesis/) - 删掉控制器里所有
@Template注解——它在 3.4 中已被废弃,且会干扰 Twig 的自动路径推导 - 检查
app/config/config.yml是否启用了templating: { engines: ['twig'] };若已弃用(推荐),则确保控制器返回的是Response对象,并显式调用$this->render()
未保存实体 ID 被当数组处理导致表单提交失败
你过去用 add('diseases') 直接绑定一堆无 ID 的 Doctrine 实体(比如新创建但未 flush 的 Disease),在 2.8 下能凑合过,在 3.4+ 会触发 “Expected argument of type \"string\", \"null\" given” 或空数组被丢弃——因为 Form 组件现在更严格校验实体的 identity。
- 不要在表单中直接传未托管(unmanaged)实体对象;改用数据传输对象(DTO)或纯数组:比如把
['diseases' => [1, 5, 9]]传入,后端再查库组装 - 如果必须传实体,确保它们已持久化(
$em->persist($d); $em->flush();),或显式设置by_reference => false并配好data_class和empty_data回调 - 注意
ChoiceType+choice_value选项:别依赖默认行为,老项目常漏写'choice_value' => 'id',升级后下拉值变空
EventDispatcher 升级后 dispatch() 报类型错误
调用 $eventDispatcher->dispatch(new UserRegisteredEvent($user)) 时抛出 Argument 1 passed to dispatch() must be object,是因为 3.x 签名从 dispatch(Event $event, string $name) 改为 dispatch(object $event, ?string $name = null),且不再接受 Symfony\Component\EventDispatcher\Event 基类。
- 把所有事件类的
use Symfony\Component\EventDispatcher\Event;换成use Symfony\Contracts\EventDispatcher\Event; - 运行
composer require symfony/contracts补齐契约包,否则类型提示不生效 - 删掉事件类里对父类
stopPropagation()、isPropagationStopped()的调用——这些方法已移除,需自行实现传播控制逻辑
CustomExceptionController 构造函数参数注入失败
自定义异常控制器报错:Cannot autowire argument $useDebugMode of "AppBundle\Controller\CustomExceptionController::__construct()": it is type-hinted "bool"。这是 Symfony 3.4 引入的严格服务注入规则:标量参数(bool, int, string)必须显式配置,不能靠猜测。
- 在
app/config/services.yml里加一段显式绑定:services: AppBundle\Controller\CustomExceptionController: arguments: $useDebugMode: '%kernel.debug%' - 确认
%kernel.debug%这个参数确实存在(它默认由 Kernel 注入,一般没问题) - 如果控制器还依赖其他标量(如
$maxRetries),同样要在这里一一列出,别指望容器自动猜







