跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

Composer怎么在脚本中使用条件判断_Composer如何根据操作系统类型执行不同的脚本命令【技巧】

Composer scripts跨平台判断需用PHP脚本中转或platform配置兜底:优先写bin/check-env.php用PHP_OS_FAMILY分支执行,纯JSON方案仅适用于CI预设平台场景。 Composer 的
scripts
怎么做跨平台条件判断 Composer 本身不支持 if/else 语法,
scripts
字段里写的只是 shell 命令字符串,直接写
[ "$OSTYPE" = "linux-gnu" ] && echo "Linux"
在 Windows 上会报错——因为 CMD/PowerShell 根本不认识方括号语法。真正能落地的方案只有两条路:靠外部脚本中转,或用 Composer 自带的
platform
+ 环境变量组合兜底。 优先写成独立脚本(如
bin/check-env.php
),在
scripts
里统一调用:
"post-install-cmd": "php bin/check-env.php"
,由 PHP 判断
PHP_OS_FAMILY
$_SERVER['OS']
,再分发命令 若坚持纯 JSON 配置,可利用 Composer 的
config.platform.php
配合环境变量,但仅适用于「预设目标平台」场景(比如 CI 中强制指定为 Linux);真实运行时仍以宿主系统为准 Windows 下 CMD 和 PowerShell 混用极易出问题:比如
npm run dev
在 CMD 可行,但在 Git Bash 里可能因路径分隔符(
/
vs
\
)失败,建议所有脚本开头加
set -e
(Bash)或
$ErrorActionPreference = "Stop"
(PowerShell)提前中断 为什么
composer.json
里的
scripts
不能直接用
&&
||
不是语法不支持,而是执行器不可控。Composer 启动脚本时,会根据当前系统选择 shell:Linux/macOS 走
/bin/sh
,Windows 默认走 CMD(哪怕你用 Git Bash 启动)。CMD 不认
&&
的短路逻辑,
command1 && command2
会被整个当做一个命令名报“找不到程序”。更隐蔽的问题是,某些命令(如
php -v
)在不同 shell 下退出码含义不一致,导致条件链断裂。
composer run-script build
实际等价于
sh -c "your-command"
(Linux/macOS)或
cmd /c "your-command"
(Windows),二者对空格、引号、重定向的解析规则完全不同 别依赖
$PATH
里有某个命令:Windows 上
find
是系统命令,Linux 上是 GNU findutils,行为差异极大;应显式用
which find
command -v find
检查 如果必须内联写,Linux/macOS 用
sh -c 'test "$(uname)" = "Linux" && echo ok'
,Windows 则只能退化为两个独立 script 条目,靠 CI 工具(如 GitHub Actions 的
if: runner.os == 'Windows'
)分发 用
symfony/console
写可复用的跨平台命令脚本 比硬塞 shell 逻辑更可持续的做法,是把条件判断收口到一个 PHP 命令行工具里。安装
symfony/console
后,你可以定义带参数和选项的命令,比如
php bin/run-platform-task.php --os=auto build
,内部用
PHP_OS_FAMILY
做分支,还能加日志、错误提示、交互确认。 Composer 2.9.6 Composer 2.9.6 是 PHP 生态中高效、稳定的依赖管理工具。此版本在性能与兼容性上进一步优化,改进了依赖解析算法,提升大型项目中的安装与更新速度。它支持并行下载任务,显著减少等待时间,并增强了与私有仓库及镜像源的交互稳定性。同时修复了多项命令行交互与内存使用相关的缺陷,确保在复杂依赖关系下依然可靠运行。无论是新项目初始化还是现有系统维护,Composer 2.9.6 都能为开发者提供流畅、精准的依赖管理体验。 下载
PHP_OS_FAMILY
PHP_OS
更可靠:返回
Linux
/
Windows
/
Darwin
,不含版本号干扰,且 PHP 7.2+ 全平台支持 避免在脚本里拼接路径:用
dirname(__DIR__)
+
PATH_SEPARATOR
,而不是硬写
../vendor/bin/xxx
,否则 Windows 下
\
/
混用会触发
file_exists()
返回 false 调试时加
echo "Running on: " . PHP_OS_FAMILY;
,别只信
php_uname('s')
——Docker 容器里它返回的是容器 OS,不是宿主,而
PHP_OS_FAMILY
是编译时确定的,更稳定 跨平台脚本最麻烦的从来不是判断逻辑,而是路径处理和子进程环境继承。比如在 Windows 上用
proc_open()
npm
,如果没显式传入
env
参数,子进程会丢失 Composer 设置的
COMPOSER_HOME
,导致缓存路径错乱。这些细节,光靠
scripts
字段的字符串根本压不住。

相关文章