post-install-cmd 应加环境与开关判断,避免误执行迁移;symfony new 前需启用 Flex 插件;console 命令必须显式指定 --env=prod;读取 composer.json 应通过 getProjectDir() 获取路径。

post-install-cmd 会无条件执行,别直接写 migrate
Composer 的 post-install-cmd 在每次 composer install(包括本地 git pull 后重装依赖)时都会触发,不区分环境、不检查数据库是否就绪。直接写 php bin/console doctrine:migrations:migrate --no-interaction 很容易导致:
- 本地开发时反复迁移,报
Migration not found或重复执行已应用的迁移 - CI 环境因缺少 DB 连接配置而失败,中断构建
- 生产部署时绕过人工确认,跳过备份或灰度验证环节
正确做法是加一层运行时判断:
"scripts": {
"post-install-cmd": [
"@php -r \"if (getenv('APP_ENV') === 'prod' && getenv('AUTO_MIGRATE')) { system('php bin/console doctrine:migrations:migrate --no-interaction'); }\""
]
}
然后在部署脚本里显式设置:AUTO_MIGRATE=1 APP_ENV=prod composer install,避免误触。
symfony new --webapp 依赖 Flex 插件,必须先放开 allow-plugins
运行 symfony new myapp --webapp 本质是调用 Composer + Flex 插件自动下载 recipe 并注入配置。如果 Composer 2.7+ 默认禁用插件,会卡在 plugins are disabled 报错,项目目录建出来但缺 public/index.php、config/packages/twig.yaml 等关键文件。
必须提前执行:
composer config -g allow-plugins true composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
验证是否生效:composer global show | grep flex 应输出 symfony/flex。否则后续所有 symfony new 都是空骨架,不是你想要的 Web 应用。
console 命令默认不读 .env,生产环境务必显式传 --env=prod
Symfony CLI 和 php bin/console 在未指定 --env 时,会 fallback 到 dev 环境,哪怕 .env 里写了 APP_ENV=prod。这会导致:
-
cache:warmup编译出 dev 模式的缓存,上线后性能崩塌 -
doctrine:schema:update误改开发库结构 - 日志写进
var/log/dev.log,监控脚本找不到prod.log
所有部署脚本中的 console 命令都应带 --env=prod:
php bin/console cache:warmup --env=prod php bin/console doctrine:migrations:migrate --no-interaction --env=prod
别依赖 .env 自动加载——它只在 Web 请求入口(public/index.php)中被 Dotenv::bootEnv() 加载,CLI 下不生效。
读取 composer.json 要用 kernel->getProjectDir(),别硬编码路径
想在 Symfony 服务里读取 composer.json 内容(比如解析 extra 字段做动态配置),不能写 file_get_contents(__DIR__.'/../../composer.json'),因为:
- 在
APP_ENV=prod且启用 OPcache 时,__DIR__可能指向var/cache/prod,路径错乱 - 项目根目录可能被 symlink,相对路径失效
- 测试环境用
Kernel::class模拟时,__DIR__指向测试目录
正确方式是依赖注入 KernelInterface,再调用:
$composerPath = $this->kernel->getProjectDir().'/composer.json';
if (!is_file($composerPath)) {
throw new \RuntimeException('composer.json not found');
}
$composer = json_decode(file_get_contents($composerPath), true);
// 只取你需要的字段,如 $composer['extra']['my-config'] ?? []
注意:必须处理 json_decode 失败、文件不可读、extra 键不存在等边界情况,别假设它一定存在。


















