curl_strerror() 函数用于返回cURL错误代码的字符串描述。这个函数在错误处理时非常有用,可以将数字错误代码转换为可读的错误消息。
curl_strerror ( int $error_code ) : string|null
| 参数 | 描述 |
|---|---|
| error_code | cURL错误代码,由 curl_errno() 或其他cURL函数返回。 |
返回错误代码的字符串描述,如果错误代码未知则返回 null。
| 错误代码 | 常量 | 描述 |
|---|---|---|
| 0 | CURLE_OK |
操作成功 |
| 1 | CURLE_UNSUPPORTED_PROTOCOL |
不支持的协议 |
| 2 | CURLE_FAILED_INIT |
初始化失败 |
| 3 | CURLE_URL_MALFORMAT |
URL格式错误 |
| 6 | CURLE_COULDNT_RESOLVE_HOST |
无法解析主机 |
| 7 | CURLE_COULDNT_CONNECT |
无法连接到主机 |
| 28 | CURLE_OPERATION_TIMEDOUT |
操作超时 |
| 35 | CURLE_SSL_CONNECT_ERROR |
SSL连接错误 |
| 47 | CURLE_TOO_MANY_REDIRECTS |
重定向过多 |
| 56 | CURLE_RECV_ERROR |
接收网络数据错误 |
| 60 | CURLE_SSL_CERTPROBLEM |
SSL证书问题 |
// 初始化cURL会话
$ch = curl_init();
// 设置一个无效的URL以产生错误
curl_setopt($ch, CURLOPT_URL, "http://invalid-url-that-does-not-exist.example");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
// 执行请求
curl_exec($ch);
// 获取错误代码和描述
if ($errno = curl_errno($ch)) {
$error_message = curl_strerror($errno);
echo "cURL错误代码: {$errno}\n";
echo "错误描述: {$error_message}\n";
echo "curl_error()返回: " . curl_error($ch) . "\n";
} else {
echo "请求成功\n";
}
curl_close($ch);
function makeCurlRequest($url, $options = []) {
$ch = curl_init();
$defaultOptions = [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; PHP cURL)'
];
curl_setopt_array($ch, array_merge($defaultOptions, $options));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($errno = curl_errno($ch)) {
$errorStr = curl_strerror($errno);
$errorMsg = curl_error($ch);
// 记录详细错误信息
error_log("cURL请求失败 - URL: {$url}, 错误代码: {$errno}, 错误描述: {$errorStr}, 详细: {$errorMsg}");
$response = [
'success' => false,
'error' => [
'code' => $errno,
'message' => $errorStr,
'detail' => $errorMsg,
'http_code' => $httpCode
],
'data' => null
];
} else {
$response = [
'success' => true,
'error' => null,
'data' => $response,
'http_code' => $httpCode,
'info' => curl_getinfo($ch)
];
}
curl_close($ch);
return $response;
}
// 使用示例
$result = makeCurlRequest('https://httpbin.org/delay/10', [CURLOPT_TIMEOUT => 3]);
if (!$result['success']) {
echo "请求失败:\n";
echo "错误代码: " . $result['error']['code'] . "\n";
echo "错误描述: " . $result['error']['message'] . "\n";
echo "详细错误: " . $result['error']['detail'] . "\n";
echo "HTTP状态码: " . $result['error']['http_code'] . "\n";
} else {
echo "请求成功,HTTP状态码: " . $result['http_code'] . "\n";
}
class CurlErrorHandler {
private static $commonErrors = [
0 => '成功',
1 => '不支持的协议',
2 => '初始化失败',
3 => 'URL格式错误',
5 => '无法解析代理',
6 => '无法解析主机',
7 => '无法连接到主机',
8 => 'FTP错误',
9 => 'FTP访问被拒绝',
28 => '操作超时',
35 => 'SSL/TLS握手失败',
47 => '重定向过多',
52 => '服务器无返回内容',
56 => '接收网络数据失败',
60 => 'SSL证书问题',
61 => '无法解码内容',
77 => 'SSL CA证书问题'
];
public static function getErrorInfo($errno) {
$errorStr = curl_strerror($errno);
$info = [
'code' => $errno,
'message' => $errorStr,
'category' => self::getErrorCategory($errno),
'suggestion' => self::getErrorSuggestion($errno),
'is_common' => isset(self::$commonErrors[$errno])
];
if (isset(self::$commonErrors[$errno])) {
$info['common_name'] = self::$commonErrors[$errno];
}
return $info;
}
private static function getErrorCategory($errno) {
$categories = [
'network' => [6, 7, 28, 56],
'ssl' => [35, 60, 77],
'protocol' => [1, 3, 47],
'configuration' => [2, 5, 9],
'server' => [52, 61]
];
foreach ($categories as $category => $codes) {
if (in_array($errno, $codes)) {
return $category;
}
}
return 'unknown';
}
private static function getErrorSuggestion($errno) {
$suggestions = [
6 => '检查主机名是否正确,DNS解析是否正常',
7 => '检查主机是否可达,端口是否开放,防火墙设置',
28 => '增加超时时间或检查网络连接',
35 => '检查SSL证书配置,尝试关闭SSL验证(仅测试环境)',
47 => '检查重定向循环,或增加CURLOPT_MAXREDIRS',
60 => '下载正确的CA证书包,或设置CURLOPT_CAINFO',
77 => '设置正确的证书路径,或禁用证书验证(仅测试环境)'
];
return $suggestions[$errno] ?? '请检查cURL配置和网络连接';
}
public static function formatErrorReport($errno, $url = '') {
$info = self::getErrorInfo($errno);
$report = "cURL错误报告\n";
$report .= "==============\n";
if ($url) {
$report .= "URL: {$url}\n";
}
$report .= "错误代码: {$info['code']}\n";
$report .= "错误描述: {$info['message']}\n";
if (isset($info['common_name'])) {
$report .= "常见名称: {$info['common_name']}\n";
}
$report .= "错误类别: " . ucfirst($info['category']) . "\n";
$report .= "建议解决方案: {$info['suggestion']}\n";
return $report;
}
}
// 使用示例
$testErrors = [6, 7, 28, 35, 47, 60, 99];
foreach ($testErrors as $errno) {
echo CurlErrorHandler::formatErrorReport($errno, 'https://example.com');
echo "---\n";
}
// 在实际请求中使用
$ch = curl_init('https://invalid-host.example');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_exec($ch);
if ($errno = curl_errno($ch)) {
echo CurlErrorHandler::formatErrorReport($errno, 'https://invalid-host.example');
$errorInfo = CurlErrorHandler::getErrorInfo($errno);
echo "\nJSON格式错误信息:\n";
echo json_encode($errorInfo, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
}
curl_close($ch);
class CurlMonitor {
private static $errorLogs = [];
private static $successCount = 0;
private static $errorCount = 0;
public static function makeRequest($url, $options = []) {
$ch = curl_init();
// 添加请求ID用于跟踪
$requestId = uniqid('curl_', true);
$startTime = microtime(true);
$defaultOptions = [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HEADER => true
];
curl_setopt_array($ch, array_merge($defaultOptions, $options));
$response = curl_exec($ch);
$endTime = microtime(true);
$info = curl_getinfo($ch);
$errno = curl_errno($ch);
$logEntry = [
'request_id' => $requestId,
'url' => $url,
'start_time' => $startTime,
'end_time' => $endTime,
'duration' => $endTime - $startTime,
'http_code' => $info['http_code'] ?? 0,
'total_time' => $info['total_time'] ?? 0,
'connect_time' => $info['connect_time'] ?? 0,
'namelookup_time' => $info['namelookup_time'] ?? 0
];
if ($errno) {
$errorStr = curl_strerror($errno);
$errorMsg = curl_error($ch);
$logEntry['error'] = [
'code' => $errno,
'message' => $errorStr,
'detail' => $errorMsg
];
self::$errorLogs[] = $logEntry;
self::$errorCount++;
// 发送错误报警(这里只是模拟)
self::sendAlert($logEntry);
} else {
$logEntry['success'] = true;
self::$successCount++;
}
curl_close($ch);
// 记录到监控日志
self::logToFile($logEntry);
return [
'request_id' => $requestId,
'success' => !$errno,
'error' => $errno ? [
'code' => $errno,
'message' => $errorStr,
'detail' => $errorMsg
] : null,
'response' => $response,
'info' => $info
];
}
private static function sendAlert($logEntry) {
// 在实际应用中,这里可以发送邮件、Slack消息等
$error = $logEntry['error'];
$message = "cURL错误报警\n";
$message .= "请求ID: {$logEntry['request_id']}\n";
$message .= "URL: {$logEntry['url']}\n";
$message .= "错误代码: {$error['code']}\n";
$message .= "错误描述: " . curl_strerror($error['code']) . "\n";
$message .= "详细错误: {$error['detail']}\n";
$message .= "发生时间: " . date('Y-m-d H:i:s') . "\n";
error_log($message);
// 如果是严重错误,可以发送额外的通知
if (in_array($error['code'], [6, 7, 28, 35])) {
// 发送到监控系统
error_log("严重cURL错误: {$error['code']} - {$logEntry['url']}");
}
}
private static function logToFile($logEntry) {
$logFile = __DIR__ . '/curl_monitor.log';
$logLine = json_encode($logEntry, JSON_UNESCAPED_UNICODE) . PHP_EOL;
// 在实际应用中,可以使用更专业的日志库
file_put_contents($logFile, $logLine, FILE_APPEND | LOCK_EX);
}
public static function getStats() {
return [
'success_count' => self::$successCount,
'error_count' => self::$errorCount,
'success_rate' => self::$successCount + self::$errorCount > 0
? round(self::$successCount / (self::$successCount + self::$errorCount) * 100, 2)
: 0,
'recent_errors' => array_slice(self::$errorLogs, -10) // 最近10个错误
];
}
public static function getErrorSummary() {
$errorSummary = [];
foreach (self::$errorLogs as $log) {
$code = $log['error']['code'];
if (!isset($errorSummary[$code])) {
$errorSummary[$code] = [
'count' => 0,
'description' => curl_strerror($code),
'last_occurrence' => '',
'urls' => []
];
}
$errorSummary[$code]['count']++;
$errorSummary[$code]['last_occurrence'] = date('Y-m-d H:i:s', (int)$log['start_time']);
$url = $log['url'];
if (!in_array($url, $errorSummary[$code]['urls'])) {
$errorSummary[$code]['urls'][] = $url;
}
}
// 按错误数量排序
uasort($errorSummary, function($a, $b) {
return $b['count'] <=> $a['count'];
});
return $errorSummary;
}
}
// 使用示例
$urls = [
'https://httpbin.org/get',
'https://httpbin.org/status/200',
'https://invalid-url.example', // 会失败
'https://httpbin.org/delay/2',
'https://httpbin.org/status/404'
];
foreach ($urls as $url) {
$result = CurlMonitor::makeRequest($url, [CURLOPT_TIMEOUT => 5]);
if (!$result['success']) {
echo "请求失败: {$url}\n";
echo "错误: " . curl_strerror($result['error']['code']) . "\n";
}
}
// 获取统计信息
$stats = CurlMonitor::getStats();
echo "\n=== 请求统计 ===\n";
echo "成功请求: {$stats['success_count']}\n";
echo "失败请求: {$stats['error_count']}\n";
echo "成功率: {$stats['success_rate']}%\n";
// 获取错误摘要
$errorSummary = CurlMonitor::getErrorSummary();
echo "\n=== 错误摘要 ===\n";
foreach ($errorSummary as $code => $summary) {
echo "错误代码 {$code} ({$summary['description']}):\n";
echo " 发生次数: {$summary['count']}\n";
echo " 最后发生: {$summary['last_occurrence']}\n";
echo " 涉及URL: " . implode(', ', array_slice($summary['urls'], 0, 3)) . "\n";
if (count($summary['urls']) > 3) {
echo " 等{$summary['count']}个URL\n";
}
echo "\n";
}
| 函数 | 返回类型 | 描述 | 示例返回值 |
|---|---|---|---|
curl_strerror() |
string|null | 根据错误代码返回标准错误描述 | "Couldn't resolve host name" |
curl_error() |
string | 返回最后一次cURL操作的详细错误信息 | "Couldn't resolve host 'invalid-host'" |
curl_errno() |
int | 返回最后一次cURL操作的错误代码 | 6 |
curl_strerror() 函数需要PHP 5.5.0或更高版本。
curl_strerror() 获取人类可读的错误描述curl_errno() 获取错误代码用于程序逻辑判断curl_error() 获取详细的错误信息用于调试curl_strerror() 为用户提供友好的错误信息A: curl_strerror() 根据错误代码返回标准的错误描述,而 curl_error() 返回最后一次cURL操作的详细错误信息。前者更通用,后者更具体。
A: 大多数常见的cURL错误代码都有对应的描述,但某些特定的或新版本的错误代码可能返回 null。建议在使用前检查返回值。
A: 建议: 1. 记录错误代码和描述到日志系统 2. 根据错误类型实现重试机制 3. 为用户提供友好的错误信息 4. 监控错误率并设置报警 5. 定期分析错误模式以改进系统