如何配置Composer在安装后自动运行PHP代码?(挂钩钩子)

2次阅读

composer.json 的 scripts 中需用正确事件名(如 post-update-cmd)和可执行格式(如 [“php”, “scripts/fix-perms.php”]),确保路径正确、权限合法、事件名全小写中划线分隔,并通过 autoload-dev 加载类方法,避免阻塞操作。

如何配置Composer在安装后自动运行PHP代码?(挂钩钩子)

composer.json 里怎么写 scripts 才能自动运行 PHP?

Composer 的 scripts 不是“安装后立刻执行任意代码”的开关,而是按明确生命周期触发的钩子。想在 composer installcomposer update 结束后跑一段 PHP,得选对事件名,且脚本必须可被 Composer 正确调用。

常见错误是直接写 php my-script.php 却忘了路径问题,或误以为 post-install-cmd 会在所有场景下触发(其实它不触发于 composer require 的首次安装)。

  • post-install-cmd:只在 composer install 时触发,且仅当 vendor/autoload.php 已存在(即不是首次安装)
  • post-update-cmd:每次 composer update 后都触发,更稳定,适合大多数“安装后动作”
  • 脚本值可以是字符串命令,也可以是数组:["php", "scripts/fix-perms.php"],推荐后者——避免 shell 解析歧义
  • 确保脚本文件有执行权限(linux/macos),且第一行没加 #!/usr/bin/env php(Composer 不走 shebang,会报错)

为什么写了 scripts 却完全没执行?

最常踩的坑是事件名拼错或没声明为“可执行”。Composer 不报错、不提示,静默跳过无效 script 条目。

检查点:

立即学习PHP免费学习笔记(深入)”;

  • 确认 composer.json 根级有 "scripts" 字段,不是嵌套在 "extra" 或其他地方
  • 事件名必须全小写、中划线分隔,比如 post-autoload-dump 不能写成 PostAutoloadDump
  • 如果脚本是 PHP 类方法,格式必须是 "MyClass::myMethod",且类已通过 autoload 加载(推荐用 autoload-dev 注册)
  • 运行时加 -v 参数:composer install -v,能看到 “Executing script …” 日志,没这行就说明根本没注册上

用 PHP 类方法当钩子,要注意什么?

比起写独立脚本文件,用类方法更易测试、可复用,但依赖加载时机很关键——post-install-cmd 触发时,vendor/autoload.php 可能还没生成,导致类找不到。

稳妥做法:

  • 把钩子逻辑放进 src/scripts/ 下,并在 composer.json"autoload-dev" 中声明 PSR-4 映射
  • 钩子方法必须是 public Static,参数可选,Composer 会传入 $Event 对象(类型 ComposerScriptEvent
  • 别在方法里直接 require 'vendor/autoload.php'——Composer 已处理好 autoloader,重复 require 可能破坏命名空间
  • 示例:"post-update-cmd": ["MyBuildScripts::clearCache"],对应 MyBuildScripts::clearCache()

性能和兼容性:这些钩子真适合干重活吗?

不适合。Composer 的 scripts 是同步阻塞执行的,卡在某个钩子上,整个 installupdate 就卡住。CI 环境尤其敏感。

  • 避免在钩子里做网络请求、文件扫描、数据库迁移——这些该交给部署脚本或 CI 流程单独跑
  • windows 用户注意:用 php script.php 比用 ./script.php 更可靠,后者在 git bash 下常因路径解析失败
  • PHP 版本兼容性:钩子脚本运行在当前 CLI PHP 环境下,和项目 require 的 PHP 版本无关。若脚本用了 match 表达式,而系统 PHP 是 8.0 以下,直接 fatal Error
  • 如果只是生成配置或清理缓存,优先用 post-autoload-dump——它比 post-update-cmd 更轻量,且每次 autoloader 更新都触发,覆盖更多场景

真正难搞的是跨平台路径拼接和钩子执行顺序——post-install-cmdpost-autoload-dump 谁先谁后?文档没明说,实测取决于是否首次安装,得自己加日志验证。

text=ZqhQzanResources