生产环境必须禁用APP_DEBUG=1,应通过symfony/error-handler捕获错误并上报至Rollbar等服务,启用SilencedErrorContext处理@静默错误,配合Monolog处理器、CI检测和缓存预热实现全链路错误监控。
生产环境必须禁用
,但错误仍需可见
开启
在生产环境会暴露敏感路径、变量和堆栈,属于严重安全风险。真正可行的方案是保留
,同时让错误被捕获、结构化、上报,而不是静默丢弃或写进混杂日志里。
关键点在于:Symfony 4.4+ 已弃用
,应统一使用
组件。它默认启用,但默认行为是仅记录到 Monolog,不主动上报。
确认
中至少有一个
指向文件(如
)且级别为
或更低
避免在生产配置中意外启用
(该选项仅用于开发调试器,非错误追踪)
默认会捕获
、
、
等,但对
静默错误无效——需额外启用
用
抓出被
压制的错误
PHP 中的
这类写法会让错误彻底消失,连日志都不进。Symfony 的
是唯一能还原这类上下文的机制,但它**不会自动启用**,必须显式配置。
在
中添加:
这会让所有被
压制的错误生成
实例,并作为上下文附加到后续异常中。配合自定义异常处理器,你就能看到「这个
出现在
第 42 行」这样的信息。
该配置仅在
或更高版本有效
若项目仍在用旧版
,请先升级,否则
不生效
注意性能:开启后每次
操作都会触发上下文收集,高频调用处慎用
把错误实时推给 Rollbar / Sentry / Datadog
Monolog 写文件只是兜底,生产环境需要的是实时告警。推荐用
的
机制桥接第三方服务,而非重写整个错误处理器。
以 Rollbar 为例,安装 SDK 后,在
中配置:
然后实现
,继承
,在
中调用
并传入
。
不要在
中直接调用 Rollbar——那会绕过 Monolog 的 channel 和 level 控制
确保
通过环境变量注入,绝不可硬编码
对敏感字段(如
、数据库连接串)做白名单过滤,
的
可完成此任务
翻译错误、模板错误等特定类型要单独监控
普通 PHP 错误只是冰山一角。Symfony Translation 缺失键、Twig 模板语法错误、路由未匹配等,都可能返回 500 却不触发
的标准流程。
必须补上两层防护:
CI 阶段强制运行
和
,失败即阻断发布
运行时在
中预加载翻译目录并 catch
,立即上报
对
的缺失键,可包装一层代理,在返回原始 key 时记录告警(如 key 包含
前缀则视为高危)
最易忽略的是缓存失效后的首次加载错误——它发生在 CLI 环境下,不会经过 Web 请求管道,必须在部署脚本中显式执行
并捕获其输出。
APP_DEBUG=1APP_DEBUG=1APP_ENV=prodsymfony/debugsymfony/error-handlerconfig/packages/prod/monolog.yamlhandlersmainerrordebug: trueerror_handlerE_ERRORE_PARSEE_COMPILE_ERROR@SilencedErrorContextSilencedErrorContext@@file_get_contents()SilencedErrorContextconfig/services.yamlservices:
Symfony\Component\ErrorHandler\ErrorHandler:
arguments:
$silencedErrorReporting: true@SilencedErrorContext@UserService.phpsymfony/error-handler ^5.4symfony/debugSilencedErrorContext@monologHandlerconfig/packages/prod/monolog.yamlmonolog:
handlers:
rollbar:
type: service
id: App\Handler\RollbarHandler
level: errorApp\Handler\RollbarHandlerMonolog\Handler\AbstractProcessingHandlerwrite()Rollbar::log()$record['context']['exception']ExceptionHandlerROLLBAR_ACCESS_TOKEN$_POSTmonologprocessorsErrorHandlerbin/console lint:translations translations/bin/console lint:twig templates/Kernel::boot()InvalidResourceExceptionTranslatorInterface::trans().error.cache:warmup