在 PHP 7.4 或更高版本中,请把命令参数与子进程环境分开:

$environment = array_replace(getenv(), [
    'http_proxy' => 'http://proxy.example:8080',
    'https_proxy' => 'http://proxy.example:8080',
]);

$process = proc_open(
    ['/usr/bin/curl', '--fail', '--max-time', '30',
     '--output', $outputFile, 'https://downloads.example/data.csv'],
    $descriptorSpec,
    $pipes,
    null,
    $environment
);

$outputFile 和 $descriptorSpec 都来自应用现有的输出处理。检查启动是否失败,管理管道,并在该生命周期内关闭进程。

array_replace(getenv(), ...) 在保留父进程环境的同时,为子进程替换这两个值。当继承来的大写代理变量和绕过变量可能改变预期路由时,请予以检查。

参数数组可避免 shell 解释凭据中的与号、美元符号或空格。shell 命令中没有嵌入任何携带账户的赋值。

本例选择 curl,因为它支持所示变量。来自 HTTP 代理列表 的地址可以为公共 HTTP 路由填入这些环境值。其他可执行文件需要其自身支持的代理接口;PHP 自带的 cURL 选项不会配置那个外部程序。

相关文章