根本原因是PATH未生效,需确认shell类型(如/bin/zsh)后将Composer路径写入~/.zshrc并执行source ~/.zshrc;scripts命令还依赖PHP版本、autoload显式引入及全局镜像配置。

composer scripts 命令为什么在终端里执行不了
不是脚本写错了,而是当前 shell 没加载到 composer 可执行文件——常见现象是:项目根目录下运行 composer hello 报 command not found: composer,但 ls /opt/homebrew/bin/composer 确实存在。
根本原因是 PATH 没生效。macOS Sonoma 及以后默认用 /bin/zsh,而很多人把 export PATH=... 写进了 ~/.bash_profile 或没加进 ~/.zshrc。
- 运行
echo $SHELL确认 shell 类型;如果是/bin/zsh,就只改~/.zshrc - 检查
~/.zshrc是否含eval "$(/opt/homebrew/bin/brew shellenv)"(推荐)或至少有export PATH="/opt/homebrew/bin:$PATH"(M 系列) - 改完必须执行
source ~/.zshrc,否则不生效 - 新开一个终端窗口验证:
which composer应输出/opt/homebrew/bin/composer
scripts 字段怎么写才真正可执行
composer.json 里的 scripts 不是写完就自动可用的,它依赖命令是否能在 shell 环境中直接调用。比如写 "build": ["rm -rf build/", "mkdir build"],如果系统没装 rm 或 mkdir(极罕见),或路径里有空格没引号包裹,就会中断。
- shell 命令要确保跨平台兼容性:避免用
gsed(需额外装 GNU sed)、gdate等非 macOS 原生命令 - PHP 脚本路径必须可访问:如
"greet": ["php scripts/greet.php"],则scripts/greet.php得存在且有执行权限(chmod +x非必需,但php要能读) - 命令数组里每项是独立 shell 调用,不会共享变量或 cd 后的路径;想切换目录得写成
"cd src && php build.php" - 别漏掉
#!/usr/bin/env php头(对 PHP 脚本非强制,但加了更健壮)
自定义命令触发后没反应或报错怎么办
运行 composer hello 没输出、卡住、或报 PHP Fatal error,通常不是 Composer 本身问题,而是脚本执行环境不对。
- 确认当前 PHP 版本:Composer 调用的是 CLI 的
php,不是 Apache 或 Nginx 用的那个;运行php -v和which php检查是否和 Homebrew 安装的一致 - 如果脚本里用了
__DIR__或getcwd(),注意它指向的是执行composer命令时的当前工作目录,不是composer.json所在目录 - 遇到
Class not found:Composer scripts 默认不自动加载 autoload,除非你显式调用require 'vendor/autoload.php' - 调试技巧:在脚本开头加
echo "PWD: " . getcwd() . "\n"; exit;,看实际执行位置
全局镜像和并发配置影响 scripts 执行速度
scripts 里如果有 composer install 或 composer require,没配好镜像和并发数,会卡在 “Downloading” 十几秒甚至超时,看起来像脚本挂了。
- 必须用正确格式设置全局镜像:
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/(注意中间的composer是 type,不能省) - 验证是否生效:
composer config -g repo.packagist输出应为完整 JSON 或 URL 字符串,空或仍是https://repo.packagist.org就是没写进去 - 并发下载必须调:
composer config -g github-protocols https(防 SSH 交互卡住),再加composer config -g concurrent-downloads 10(默认仅 3) - 这些配置只对当前用户生效,不同用户得各自运行一遍
最容易被忽略的是:scripts 里的命令默认不继承项目级 composer.json 的 config 设置,所有加速、镜像、超时等参数,都得靠全局配置兜底。没配全局,哪怕项目里写了 "config": {"fxp-asset": {}} 也没用。











