应利用 composer 的 pre-install-cmd 和 pre-update-cmd 钩子,在命令执行前调用封装好的 php 测速脚本(如 bin/check-mirror.php),通过 curl 的 curlinfo_starttransfer_time 精确测定各镜像响应速度,动态配置当前项目 repo.packagist,并启用本地缓存避免重复测速。

Composer install/update 前如何自动触发测速逻辑
不能靠手动改 composer.json 或临时设 COMPOSER_REPO_PACKAGIST,得让 Composer 在执行 install 或 update 命令前,先跑一段测速脚本,再动态写入最快镜像地址。核心是利用 Composer 的 pre-install-cmd 和 pre-update-cmd 钩子——它们在命令真正执行前触发,且支持调用外部 PHP 脚本。
关键点:钩子脚本必须返回 0,否则后续命令会被中断;测速结果需写入本地 auth.json 或通过 config repo.packagist 覆盖全局配置。
- 推荐把测速逻辑封装成独立 PHP 文件(如
bin/check-mirror.php),避免钩子里写大段 shell - 钩子中不要用
exec('composer config ...')直接改全局配置,容易污染其他项目;应限定作用域为当前项目,用--global要格外谨慎 - 测速目标 URL 必须带
/packages.json(如https://mirrors.aliyun.com/composer/packages.json),否则响应不具可比性
测速脚本怎么判断哪个镜像最快
不是 ping 延时,而是真实发起一次 HTTP HEAD 请求并统计 time_namelookup + time_connect + time_starttransfer。Packagist 官方镜像和国内主流镜像(阿里云、腾讯云、华为云、PHPChina)都支持 packages.json 的轻量访问,适合做基准测试。
示例片段(bin/check-mirror.php):
$urls = [
'https://packagist.org/packages.json',
'https://mirrors.aliyun.com/composer/packages.json',
'https://mirrors.tencent.com/composer/packages.json',
];
foreach ($urls as $url) {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_NOBODY => true,
CURLOPT_TIMEOUT => 5,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => false,
CURLOPT_FOLLOWLOCATION => true,
]);
curl_exec($ch);
$speed = curl_getinfo($ch, CURLINFO_STARTTRANSFER_TIME);
curl_close($ch);
$results[$url] = $speed ?: 999;
}
$best = array_keys($results, min($results))[0];
// 写入当前项目配置
exec("composer config repo.packagist composer {$best}");
注意:CURLINFO_STARTTRANSFER_TIME 比 total_time 更可靠——它排除了 body 下载耗时,聚焦在镜像服务响应能力上。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
为什么不能直接在钩子里用 shell 测速
因为 Windows、macOS、Linux 对 curl / wget 的参数兼容性差,比如 --write-out 在 macOS 自带 curl 中不可用,time 命令输出格式也不统一。PHP 的 cURL 扩展跨平台一致,且能精确控制超时与重定向行为。
- Shell 方案在 CI 环境(如 GitHub Actions 的 ubuntu-latest)常因缺少
curl或版本太老失败 - PHP 脚本可明确指定最低要求(如
"ext-curl": "*"),Composer 会提前校验 - 钩子中调用
php bin/check-mirror.php比拼接长 shell 字符串更易调试和复用
镜像替换后如何避免下次重复测速
测速本身有开销(通常 2–4 秒),不应每次命令都跑。建议加缓存机制:记录上次测速时间与镜像地址到 .mirror-cache.json,仅当缓存超过 24 小时或当前镜像不可达时才重测。
在测速脚本开头加入:
$cache = '.mirror-cache.json';
if (file_exists($cache)) {
$data = json_decode(file_get_contents($cache), true);
if (time() - $data['ts'] $best, 'ts' => time()]));
这个缓存文件应加入 .gitignore,且注意 @get_headers 的静默错误抑制——避免因 DNS 或网络抖动误判镜像失效。
最易被忽略的是:测速脚本自身依赖的扩展(如 ext-curl)必须在 Composer 运行环境里可用;Docker 环境中常因精简镜像缺失该扩展,导致钩子静默失败——务必在 CI 或部署脚本里显式检查 php -m | grep curl。










