curl_errno返回0而不是6

时间:2012-02-24 06:17:12

标签: php curl libcurl curl-multi

$data_struct = array(); 

$data_struct[]['opts'] = array( CURLOPT_URL => 'http://www.yahoo.com/', CURLOPT_RETURNTRANSFER => true);
$data_struct[]['opts'] = array( CURLOPT_URL => 'http://www.google.com/', CURLOPT_RETURNTRANSFER => true);
$data_struct[]['opts'] = array( CURLOPT_URL => 'http://404.php.net/', CURLOPT_RETURNTRANSFER => true);

//create the multiple cURL handle
$mh = curl_multi_init();

// create and add handles to data structure
foreach ($data_struct as $i => $data){
   $data_struct[$i]['handle'] = curl_init();
   curl_setopt_array($data_struct[$i]['handle'], $data_struct[$i]['opts']);
   curl_multi_add_handle($mh, $data_struct[$i]['handle']);
}  

$active = null;
//execute the handles
do {
    $mrc = curl_multi_exec($mh, $active);    

} while ($mrc == CURLM_CALL_MULTI_PERFORM);

while ($active && $mrc == CURLM_OK) {
    if (curl_multi_select($mh) != -1) {
        do {
            $mrc = curl_multi_exec($mh, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    }
}    

foreach ($data_struct as $i => $data){
   $row = array();
   $row['httpcode'] = curl_getinfo($data_struct[$i]['handle'] , CURLINFO_HTTP_CODE);
   $row['url'] = $data['opts'][CURLOPT_URL];
   $row['error'] = curl_error($data_struct[$i]['handle']);
   $row['errorno'] = curl_errno($data_struct[$i]['handle']);
   print_r($row);
   echo "\n";       

   curl_multi_remove_handle($mh, $data_struct[$i]['handle']);
   curl_close($data_struct[$i]['handle']);
}

输出

Array
(
    [httpcode] => 302
    [url] => http://www.yahoo.com/
    [error] => 
    [errorno] => 0
)

Array
(
    [httpcode] => 302
    [url] => http://www.google.com/
    [error] => 
    [errorno] => 0
)

Array
(
    [httpcode] => 0
    [url] => http://404.php.net/
    [error] => Couldn't resolve host '404.php.net'
    [errorno] => 0
)

在相同的情况下,尽管curl_error返回错误消息,但多个curl返回0并使用curl_errno函数。

2 个答案:

答案 0 :(得分:4)

如果您有PHP 5.2.x or greater(此处更新更好),我建议您使用curl_multi_info_read()。 (见:curl_multi_info_read() docs。)

您可以将curl_multi_info_read()的输出放在代码的末尾附近(在echo "\n";行之后),如下所示:

var_dump(curl_multi_info_read($mh));

这似乎给出了正确的错误(特别是"result" => 6):

Array
(
    [httpcode] => 0
    [url] => http://404.php.net/
    [error] => Couldn't resolve host '404.php.net'
    [errorno] => 0
)

array(3) {
  ["msg"]=>
  int(1)
  ["result"]=>
  int(6)
  ["handle"]=>
  resource(7) of type (curl)
}

注意:在PHP 5.2.8安装上测试过。

答案 1 :(得分:0)

代码阵列:

$codes_texts = [
    0  => 'OK',
    1  => 'UNSUPPORTED_PROTOCOL',
    2  => 'FAILED_INIT',
    3  => 'URL_MALFORMAT',
    4  => 'URL_MALFORMAT_USER',
    5  => 'COULDNT_RESOLVE_PROXY',
    6  => 'COULDNT_RESOLVE_HOST',
    7  => 'COULDNT_CONNECT',
    8  => 'FTP_WEIRD_SERVER_REPLY',
    9  => 'FTP_ACCESS_DENIED',
    10 => 'FTP_USER_PASSWORD_INCORRECT', 
    11 => 'FTP_WEIRD_PASS_REPLY', 
    12 => 'FTP_WEIRD_USER_REPLY', 
    13 => 'FTP_WEIRD_PASV_REPLY', 
    14 => 'FTP_WEIRD_227_FORMAT', 
    15 => 'FTP_CANT_GET_HOST', 
    16 => 'FTP_CANT_RECONNECT', 
    17 => 'FTP_COULDNT_SET_BINARY', 
    18 => 'PARTIAL_FILE', 
    19 => 'FTP_COULDNT_RETR_FILE',
    20 => 'FTP_WRITE_ERROR', 
    21 => 'FTP_QUOTE_ERROR', 
    22 => 'HTTP_NOT_FOUND', 
    23 => 'WRITE_ERROR', 
    24 => 'MALFORMAT_USER', 
    25 => 'FTP_COULDNT_STOR_FILE', 
    26 => 'READ_ERROR',
    27 => 'OUT_OF_MEMORY', 
    28 => 'OPERATION_TIMEOUTED', 
    29 => 'FTP_COULDNT_SET_ASCII', 
    30 => 'FTP_PORT_FAILED', 
    31 => 'FTP_COULDNT_USE_REST', 
    32 => 'FTP_COULDNT_GET_SIZE', 
    33 => 'HTTP_RANGE_ERROR', 
    34 => 'HTTP_POST_ERROR', 
    35 => 'SSL_CONNECT_ERROR', 
    36 => 'FTP_BAD_DOWNLOAD_RESUME', 
    37 => 'FILE_COULDNT_READ_FILE', 
    38 => 'LDAP_CANNOT_BIND', 
    39 => 'LDAP_SEARCH_FAILED', 
    40 => 'LIBRARY_NOT_FOUND', 
    41 => 'FUNCTION_NOT_FOUND', 
    42 => 'ABORTED_BY_CALLBACK', 
    43 => 'BAD_FUNCTION_ARGUMENT', 
    44 => 'BAD_CALLING_ORDER', 
    45 => 'HTTP_PORT_FAILED', 
    46 => 'BAD_PASSWORD_ENTERED', 
    47 => 'TOO_MANY_REDIRECTS', 
    48 => 'UNKNOWN_TELNET_OPTION', 
    49 => 'TELNET_OPTION_SYNTAX', 
    50 => 'OBSOLETE', 
    51 => 'SSL_PEER_CERTIFICATE', 
    52 => 'GOT_NOTHING', 
    53 => 'SSL_ENGINE_NOTFOUND', 
    54 => 'SSL_ENGINE_SETFAILED', 
    55 => 'SEND_ERROR', 
    56 => 'RECV_ERROR', 
    57 => 'SHARE_IN_USE', 
    58 => 'SSL_CERTPROBLEM', 
    59 => 'SSL_CIPHER', 
    60 => 'SSL_CACERT', 
    61 => 'BAD_CONTENT_ENCODING', 
    62 => 'LDAP_INVALID_URL', 
    63 => 'FILESIZE_EXCEEDED', 
    64 => 'FTP_SSL_FAILED', 
];

<强>脚本:

$urls = array(
    "http://php.net/",
    "http://404.php.net/",
    "httpnot://php.net/",
);

$mh         = curl_multi_init();
$codes      = [];
$result    = [];
$connects  = [];

foreach ($urls as $i => $url) {
    $connects[$i] = curl_init($url);
    curl_setopt($connects[$i], CURLOPT_RETURNTRANSFER, 1);
    curl_multi_add_handle($mh, $connects[$i]);
}

do {
    $status = curl_multi_exec($mh, $active);
    $info = curl_multi_info_read($mh, $count);
    if ($info !== false) {
        $codes[(int)$info['handle']] = (int)$info['result'];
    }
}
while ($status === CURLM_CALL_MULTI_PERFORM || $active || $count);

foreach ($connects as $i => $connect) {
    $result[$i] = [
        'url'       => $urls[$i],
        'code'      => $codes[(int)$connect], // 0 - 64 = curl_errno
        'code_text' => $codes_texts[$codes[(int)$connect]],
        'body_len'  => strlen(curl_multi_getcontent($connect)),
    ];
    curl_close($connect);
}

curl_multi_close($mh);

echo "<pre>" . var_export($result, 1) . "</pre>";

<强>结果:

array (
  0 => 
  array (
    'url' => 'http://php.net/',
    'code' => 0,
    'code_text' => 'OK',
    'body_len' => 34462,
  ),
  1 => 
  array (
    'url' => 'http://404.php.net/',
    'code' => 6,
    'code_text' => 'COULDNT_RESOLVE_HOST',
    'body_len' => 0,
  ),
  2 => 
  array (
    'url' => 'httpnot://php.net/',
    'code' => 1,
    'code_text' => 'UNSUPPORTED_PROTOCOL',
    'body_len' => 0,
  ),
)