答案是curl.cainfo和openssl.cafile必须配对指向同一绝对路径的最新cacert.pem文件,路径需加双引号(windows)、不可用~或相对路径,且须通过php --ini和openssl_get_cert_locations()验证有效性并重启终端。

php.ini里curl.cainfo和openssl.cafile没配对
这两个配置必须指向同一个cacert.pem文件,且路径必须是绝对路径。Windows下漏写双引号、macOS用~开头、Linux写相对路径,都会让PHP静默忽略配置。
先运行php --ini确认CLI模式加载的是哪个php.ini,再执行php -r "print_r(openssl_get_cert_locations());",重点核对default_cert_file和ini_cafile是否一致、是否存在、文件大小是否大于100KB(Mozilla官方证书包约300KB)。常见错误:路径存在但权限为000,或文件被杀毒软件清空。
curl.cainfo="/usr/local/etc/php/cacert.pem"openssl.cafile="/usr/local/etc/php/cacert.pem"
系统时间偏差超过2分钟触发证书过期误判
证书校验依赖本地时钟,偏差超2分钟就会报SSL certificate problem: certificate has expired——不是证书真过期,而是你的时间快了5分钟或慢了3分钟。
Linux/macOS执行timedatectl status | grep "System clock synchronized",输出yes才算校准成功;Windows需以管理员身份运行w32tm /resync,失败时先net start w32time再重试。别信任务栏右下角的“已同步”,它只是一次性动作。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 偏差>2分钟必须修复,临时禁用SSL验证不解决根本问题
- 容器环境默认禁用NTP,
docker run时要加--cap-add=SYS_TIME或挂载宿主机时间
Composer config --global cafile基本无效
这个命令只影响Composer自身HTTP客户端,但composer install过程中解析composer.json、校验签名、下载zip包等环节,全走PHP底层cURL或stream_context_create(),绕不开php.ini里的openssl.cafile。
尤其在CI/CD、Docker、Web服务器环境下,用户级配置完全不生效。如果你在GitHub Actions里写了composer config --global cafile却仍报错,99%是因为没改对运行时PHP的php.ini。
- CI中优先用
sed -i直接修改php.ini,而非依赖Composer命令 - Web环境要确认CLI和FPM加载的是同一份
php.ini,否则CLI能跑、网页报错
下载的cacert.pem文件本身损坏或过期
别用系统自带的/etc/ssl/certs/ca-bundle.crt或PHP ZIP包附带的旧证书。必须从https://curl.se/ca/cacert.pem下载最新版,该文件2026年仍在持续更新。
下载后检查文件内容:开头是-----BEGIN CERTIFICATE-----,结尾是-----END CERTIFICATE-----,中间不能有乱码或截断。Windows下用记事本保存可能引入BOM头,推荐用VS Code或Notepad++另存为UTF-8无BOM格式。
- 路径示例:
C:\php\extras\ssl\cacert.pem(Windows)、/etc/ssl/certs/cacert.pem(Linux) - 改完
php.ini后必须关闭当前终端,新开一个——PHP CLI不会热加载配置
php.ini里curl.cainfo路径写错 + 下载的cacert.pem只有几KB。逐项验证比猜更快。










