应避免用 composer run-script 启动 parallel-lint,因其已被弃用且无法透传参数、不支持 pcntl_fork;正确做法是通过独立 shell 脚本封装并用 composer run 调用,或在 pcntl 不可用时改用 npm-run-all 并行多个 php -l。

别用 composer run-script 启动 parallel-lint —— 它已被弃用,且无法透传参数给子进程,容易导致并发数失控或静默失败。
为什么 parallel-lint 不能直接塞进 scripts 字符串里?
parallel-lint 是一个 CLI 工具,依赖 pcntl_fork 实现真正的多进程,而 Composer 脚本执行器(尤其是旧版)默认以单线程 shell 模式调用命令,会禁用或忽略 pcntl 扩展。常见现象是:
- 终端卡住、无输出,
ps aux | grep parallel-lint显示只有 1 个进程在跑 - 即使加了
-j 8参数,实际只启用 1 个 worker - PHP 报错
pcntl_fork() has been disabled for security reasons(尤其在 shared hosting 或某些 Docker 基础镜像中)
根本原因不是 parallel-lint 写错了,而是 Composer 的脚本执行环境不保证 pcntl 可用,也不接管子进程生命周期。
正确做法:用 composer run + 独立 shell 封装
把 parallel-lint 命令从 scripts 字段中“解耦”出来,改用 shell 脚本封装,并通过 composer run 触发该脚本。这样能绕过 Composer 对进程模型的干预。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 在项目根目录新建
bin/lint-parallel(记得chmod +x bin/lint-parallel) - 内容示例(兼容 Linux/macOS/Windows WSL):
#!/usr/bin/env bash # bin/lint-parallel vendor/bin/parallel-lint --exclude vendor --exclude node_modules --jobs 6 --colors "$@" src/ tests/
- 在
composer.json的scripts中定义:"lint:parallel": "bin/lint-parallel"
- 运行:
composer run lint:parallel(注意:不用run-script)
传参和 CI 兼容性要点
parallel-lint 经常需要动态指定路径或开关(比如只检 Git 暂存区文件),必须确保参数能透传到最终命令。
- 脚本里用
"$@"接收所有参数,否则composer run lint:parallel -- --only-staged会失效 - CI 环境(如 GitHub Actions)默认不加载
pcntl,需显式启用:php -d extension=pcntl.so vendor/bin/parallel-lint ... - Windows CMD 下无法运行
bin/lint-parallel,应提供备用方案:"lint:parallel": "php -d extension=pcntl vendor/bin/parallel-lint --exclude vendor --jobs 4 src/ tests/"
(注意:Windows PHP 默认不带pcntl,此写法仅适用于已编译该扩展的环境)
替代方案:用 npm-run-all 并行多个单进程 lint 工具
如果 pcntl 确实不可用(例如 Alpine Linux 容器、部分云函数平台),放弃 parallel-lint,转用多个轻量 lint 工具并行:
- 安装:
npm install --save-dev npm-run-all - 定义三个脚本:
"lint:src": "php -l src/", "lint:tests": "php -l tests/", "lint:config": "php -l config/"
- 组合并行:
"lint:all": "run-p lint:src lint:tests lint:config"
- 运行:
composer run lint:all
虽然不是真正“一个进程扫全量”,但规避了 pcntl 依赖,且各 php -l 进程天然独立,稳定性更高。真正难搞的从来不是并发数,而是子进程是否被父环境信任和放行。










