Composer不支持在scripts中直接写PHP代码,PHP回调需通过@php执行独立PHP文件,该文件加载自动加载器、实例化类并调用方法;必须手动require autoload.php,类需已配置autoload,路径用__DIR__,参数通过--透传并在脚本中解析,必须用@php保证PHP环境一致,且需显式exit(1)传递错误码。

Composer 不支持直接在 scripts 字段里写 PHP 代码,所谓“PHP 回调脚本”,本质是:用类方法作为可执行入口,由 Composer 调用时通过 @php 执行一个包装好的 PHP 文件 —— 这个文件负责加载自动加载器、实例化类、调用指定方法。
PHP 回调必须写成独立文件,不能直接定义在 composer.json 中
很多人误以为可以在 scripts 里写 "post-install-cmd": "MyClass::doSomething",这是错的。Composer 的 scripts 只接受 shell 命令字符串或数组,不解析 PHP 语法。
-
composer.json里只能写类似"post-install-cmd": "@php scripts/init.php" - 对应
scripts/init.php必须手动require __DIR__ . '/vendor/autoload.php'; - 类必须已通过
autoload配置(如 PSR-4)声明,否则new MyClass()会报Class not found - 不要依赖当前工作目录:用
__DIR__定位路径,比如配置文件读取写__DIR__ . '/../config/app.php'
如何定义和调用带参数的 PHP 回调脚本
Composer 本身不解析脚本参数,但支持将 -- 后的内容透传给命令。你需要在 PHP 脚本里自己处理 $argv。
- 在
composer.json中定义:"dev:build": "@php scripts/build.php" - 运行时传参:
composer dev:build -- --env=prod --force -
scripts/build.php开头要跳过脚本名:$args = array_slice($argv, 1); - 推荐用
symfony/console或轻量解析库(如league/climate)处理参数,避免手写strpos($arg, '--env=')
@php 和 php 的区别不是可有可无,而是环境一致性关键
写 php scripts/init.php 看似省事,但在多 PHP 版本环境(如 asdf、phpbrew、Docker)下极易出错 —— php 走系统 PATH,而 composer install 可能用的是另一个 PHP 二进制。
立即学习“PHP免费学习笔记(深入)”;
-
@php由 Composer 内部解析,始终指向它启动时使用的 PHP 可执行文件 - 如果你的脚本依赖
ext-redis或ext-sodium,用错 PHP 就直接Fatal error - Windows 下
@php自动适配php.exe,不用额外写.bat兼容逻辑 - CI/CD 流水线中尤其要强制用
@php,否则本地能跑、CI 报错的问题反复出现
最易被忽略的一点:PHP 回调脚本的错误退出码不会自动触发 Composer 中断。即使 scripts/init.php 中 exit(1),post-install-cmd 仍算“成功”。需要显式在脚本末尾加 if ($failed) { exit(1); },否则后续钩子照常执行,问题会被掩盖。



















