Composer不支持中文事件名,必须使用英文键名如post-install-cmd;中文路径需显式转码,PHP类Hook须手动引入autoload.php并确保命名空间匹配。

Composer 不支持中文事件名,所谓“中文 Hook”只是开发者用中文写注释、日志或配置文件,事件本身必须用英文(如 post-install-cmd),否则完全不触发。
为什么写成 "部署脚本": "php deploy.php" 就不执行?
Composer 只识别预定义的英文事件名,"部署脚本" 这种键名会被直接忽略——它既不是官方生命周期事件,也不是可被 composer run 调用的自定义命令键。常见错误包括:
- 把中文键名当钩子用,误以为能自动触发
- 在
extra或autoload下写scripts,导致整个字段被跳过 - 用了全角冒号、空格或引号(如
"deploy:prod"),shell 解析失败
正确做法是:用语义清晰的英文键名,比如 "deploy:prod" 或 "sync:assets",再在脚本里输出中文日志。
如何让 post-install-cmd 稳定触发并兼容中文路径?
这个事件只在 composer install 真正安装依赖时运行,不是每次执行都触发。要让它可靠工作,注意以下几点:
- 确保
composer.json顶层有"scripts": {"post-install-cmd": [...]},不能嵌套 - 避免依赖尚未生成的 autoloader:首次
install时vendor/autoload.php已存在,但类可能未注册;若需用第三方类,改用post-autoload-dump - 中文路径要用
mb_convert_encoding()或iconv()显式转码,尤其在 Windows 上读取config/数据库连接.json类文件时 - 别用
file_get_contents('配置文件.json')直接读——PHP 默认按 ISO-8859-1 解码,UTF-8 中文会乱码;应加stream_context_create(['http' => ['header' => 'Content-Type: application/json; charset=utf-8']])
用 PHP 类写 Hook 时,为什么总报 Class not found?
Composer 不自动加载 vendor/autoload.php 到脚本上下文,这是设计使然,不是 bug。即使类已声明在 autoload 中,也得手动引入:
// scripts/DeployHook.php
require __DIR__ . '/../vendor/autoload.php';
<p>use App\Scripts\DeployHook;</p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/xiazai/skill10050" title="Academic Composer Upload"><img
src="https://img.php.cn/upload/skill/001/246/273/6adaf20d79f23518.jpg" alt="Academic Composer Upload" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/xiazai/skill10050" title="Academic Composer Upload">Academic Composer Upload</a>
<p>辅助学术写作,包括查找资料、生成大纲、引用扩写及润色风格,同时确保引用规范。</p>
</div>
<a href="/xiazai/skill10050" title="Academic Composer Upload" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div><p>class DeployHook
{
public static function onPostInstall($event)
{
$io = $event->getIO();
$io->writeError('✅ 正在加载中文配置...');
// 此处才能安全使用 Illuminate\Support\Facades... 等类
}
}关键点:
-
__DIR__指向当前脚本目录,路径错一级就找不到autoload.php - 类必须已通过
composer dump-autoload注册,且命名空间与autoload配置匹配 - 方法参数签名要对:
public static function onPostInstall($event),不能少参数或类型提示 - 不要在脚本里写
die()或exit(),会中断 Composer 主流程
想实现“部署完成发钉钉通知”,该用 shell 还是 PHP?
涉及签名计算、环境变量读取、多步骤组装消息体时,PHP 更可靠。钉钉 Webhook 要求 timestamp 和 sign(HMAC-SHA256),shell 里难维护:
// scripts/notify-dingtalk.php
require __DIR__ . '/../vendor/autoload.php';
<p>use GuzzleHttp\Client;</p><p>$timestamp = time() * 1000;
$secret = getenv('DINGTALK_SECRET') ?: '';
$sign = base64_encode(hash_hmac('sha256', "$timestamp\n$secret", $secret, true));</p><p>$client = new Client();
$client->post(getenv('DINGTALK_WEBHOOK'), [
'json' => [
'msgtype' => 'text',
'text' => ['content' => "? 项目部署完成(环境:" . (getenv('APP_ENV') ?: 'unknown') . ")"],
'timestamp' => $timestamp,
'sign' => $sign,
],
]);然后在 composer.json 里配:
"post-install-cmd": ["php scripts/notify-dingtalk.php"]
注意:post-install-cmd 在 CI/CD 或线上部署中不一定适用——它依赖本地 composer install 执行,而很多生产环境是先打包再分发,此时钩子根本没机会跑。真正稳的做法是把这类逻辑抽离为独立 bin/deploy 脚本,由运维工具统一调用。

















