Composer 要求 callable 脚本必须用数组格式 ["ClassName", "methodName"],不可写为 "ClassName::methodName";类需可自动加载,方法须为 public static,参数需通过 $event->getArguments() 获取,调试应先验证类与方法是否存在。

脚本值写成 "ClassName::methodName" 会直接报错
这种写法看似直观,但 PHP 解析器会在 composer.json 解析阶段就拒绝:它不识别 "AppScript::run" 这种字符串作为可执行脚本值。Composer 会抛出类似 Script not found 或 Invalid script definition 的错误,根本不会走到调用环节。
必须用数组格式 ["ClassName", "methodName"]
Composer 要求 callable 类型脚本必须以索引数组形式声明,且第一个元素是完整类名(含命名空间),第二个是方法名。例如:
"post-update-cmd": ["App\ScriptHandler", "onPostUpdate"]
注意反斜杠要双写(JSON 字符串转义),实际运行时等价于 ['AppScriptHandler', 'onPostUpdate']。这个数组会被 Composer 内部传给 call_user_func 执行。
- 类必须已声明或能被自动加载(检查
autoload配置是否覆盖该路径) - 方法必须是
public static,非静态或 private/protected 会触发调用失败 - 不支持带参数的静态方法定义(如
["MyClass", "do", "arg1"]),参数需通过$event->getArguments()或环境变量传递
脚本里拿不到 $argv,要用 $event->getInput() 或 $event->getArguments()
当运行 composer run-script deploy -- --env=prod --force 时,-- 后的参数不会自动塞进 $argv。Callable 脚本接收的是 ComposerScriptEvent 对象,参数得从里面取:
立即学习“PHP免费学习笔记(深入)”;
public static function deploy(ComposerScriptEvent $event) {
$args = $event->getArguments(); // 返回 ['--env=prod', '--force']
// 手动解析,或用 SymfonyConsoleInputArrayInput 封装
}常见坑是直接写 global $argv —— 它始终为空,因为 Composer 并未把参数透传给 PHP 运行时的全局变量。
类没加载、方法不存在、命名空间写错,错误信息很模糊
Composer 报错常统一显示 Script ... handling the ... event returned with error code 255,不提示具体哪一行出问题。真实原因可能是:
-
Class 'AppScriptHandler' not found:类文件路径与 PSR-4 声明不一致,或vendor/autoload.php没生效 -
Call to undefined method AppScriptHandler::onPostUpdate():方法名拼错,或不是 static - 使用了
$this或依赖实例属性:静态方法里不能访问$this,否则报Fatal error: Uncaught Error: Using $this when not in object context
最稳的调试方式是先在命令行手动运行 php -r "var_dump(class_exists('AppScriptHandler'));",确认类可加载,再验证方法存在性。



















