When using curl_multi_exec()
, you'll need to use curl_multi_info_read()
to get the error code for specific handles. This is due to the way PHP interfaces with cURL in its easy and multiple interfaces, and how error codes are fetched on individual handles from cURL's curl_multi_info_read() function (see explanation below).
Basically, if you are using multi handles, calling curl_errno()
and curl_error()
are not reliable or accurate.
See this modified example from the manual:
<?php
$urls = array(
"http://www.cnn.com/",
"http://www.bbc.co.uk/",
"http://www.yahoo.com/",
'http://wijgeiwojgieowjg.com/',
'http://www.example.com/',
);
$infos = array();
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_RETURNTRANSFER, 1);
if (strpos($url, 'example.com') !== false) {
// set a really short timeout for one url
curl_setopt($conn[$i], CURLOPT_TIMEOUT_MS, 10);
}
curl_multi_add_handle($mh, $conn[$i]);
}
do {
$status = curl_multi_exec($mh, $active);
if (($info = curl_multi_info_read($mh)) !== false) {
$infos[$info['handle']] = $info;
}
} while ($status === CURLM_CALL_MULTI_PERFORM || $active);
foreach ($urls as $i => $url) {
$info = $infos[$conn[$i]];
echo "$url returned code {$info['result']}";
if (version_compare(PHP_VERSION, '5.5.0') >= 0) {
echo ": " . curl_strerror($info['result']);
}
echo "\n";
if ($info['result'] === 0) {
$res[$i] = curl_multi_getcontent($conn[$i]);
}
curl_close($conn[$i]);
}
Output:
http://www.cnn.com/ returned code 0
http://www.bbc.co.uk/ returned code 0
http://www.yahoo.com/ returned code 0
http://wijgeiwojgieowjg.com/ returned code 6
http://www.example.com/ returned code 28
Explanation:
Specifically, this is due to how PHP's curl_exec()
calls cURL's curl_easy_perform
which returns a CURLcode (error code) and PHP specifies the cURL option CURLOPT_ERRORBUFFER which causes a buffer to automatically get filled with an error message if one occurs.
But when using PHP's curl_multi_exec()
, PHP calls cURL's curl_multi_perform
which returns immediately and doesn't return error codes for the multi handles. You must call cURL's curl_multi_info_read
function to get error codes for the individual handles.
PHP 5.5.0 provides a wrapper to cURL's curl_easy_strerror()
which returns a string corresponding to a curl error code.