Making HTTP Requests with cURL

The curl 3,008 extension wraps libcurl (8.18.0 here): curl_init(), options, curl_exec(), then curl_getinfo(). Handles are freed automatically, and curl_close() is deprecated in PHP 8.5.

A GET with timeouts, a timeout failure, parallel requests and a streamPHP
<?php
$api = 'http://127.0.0.1:8218';
$ch = curl_init("$api/products/1");
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT_MS => 500,
  CURLOPT_TIMEOUT_MS => 2000, CURLOPT_HTTPHEADER => ['Accept: application/json']]);
$body = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), ' ', curl_getinfo($ch, CURLINFO_CONTENT_TYPE),
  ' ', json_decode($body, flags: JSON_THROW_ON_ERROR)->title, "\n";
curl_setopt_array($ch, [CURLOPT_URL => "$api/slow", CURLOPT_TIMEOUT_MS => 300]);
if (curl_exec($ch) === false) echo 'error ', curl_errno($ch), ': ', curl_error($ch), "\n";
$mh = curl_multi_init();                    // three slow calls at once; bodies go to stdout
foreach (range(1, 3) as $i) curl_multi_add_handle($mh, curl_init("$api/slow"));
$start = hrtime(true);
do { curl_multi_exec($mh, $running); curl_multi_select($mh); } while ($running > 0);
printf("%d in %.2f s\n", count(curl_multi_get_handles($mh)), (hrtime(true) - $start) / 1e9);
$ctx = stream_context_create(['http' => ['timeout' => 2, 'ignore_errors' => true]]);
echo file_get_contents("$api/products/9", false, $ctx), http_get_last_response_headers()[0];
Output
200 application/json Modern PHP in Practice
error 28: Operation timed out after 300 milliseconds with 0 bytes received
{"pid":199474,"waited":true}
{"pid":187722,"waited":true}
{"pid":187726,"waited":true}
3 in 0.81 s
{"title":"No product 9"}
HTTP/1.1 404 Not Found

Set both timeouts: CURLOPT_TIMEOUT defaults to no limit, so a stuck upstream can hold an FPM worker (Performance and OPcache). curl_exec() returns false only when the transport fails, and a 404 is a normal response. The three 0.8 s calls ran in parallel. A stream context (Stream Contexts) needs ignore_errors to keep error bodies.