For PHP 7.4 or later, keep the command arguments and child environment separate:

$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 and $descriptorSpec come from the application's existing output handling. Check for a failed launch, manage the pipes and close the process through that lifecycle.

array_replace(getenv(), ...) preserves the parent environment while replacing these two values for the child. Review inherited uppercase proxy and bypass variables when they could change the intended route.

The argument array keeps a shell from interpreting credential ampersands, dollar signs or spaces. There is no account-bearing assignment embedded in a shell command.

This example selects curl because it supports the variables shown. An address from the HTTP proxy list can fill those environment values for a public HTTP route. A different executable needs its supported proxy interface; PHP's own cURL options do not configure that external program.

Artiglyn mynjee