PHP中解析CURL返回的HTTP状态码及URL有效性验证方案
好问题!咱们一步步来解决你的两个核心需求:区分curl返回状态码0的不同原因,以及构建可靠的URL验证逻辑。
一、区分curl返回HTTP状态码0的两种情况
当curl返回的$httpCode为0时,本质是curl_exec($ch)执行失败了——此时不能只看状态码,得通过curl_errno($ch)获取具体的错误码,不同的错误码对应不同的场景:
- 主机不存在:对应错误码
CURLE_COULDNT_RESOLVE_HOST(数值6),说明DNS解析失败,找不到这个域名对应的IP地址。 - 服务器拒绝连接:对应错误码
CURLE_COULDNT_CONNECT(数值7),表示DNS解析成功,但目标服务器拒绝了连接请求(比如端口未开放、防火墙拦截等)。 - 另外还有
CURLE_OPERATION_TIMEDOUT(数值28),这是连接或请求超时的情况,也可以单独区分出来。
你可以修改原代码中的判断逻辑,精准提示错误类型:
else if($httpCode == 0) { $curlErrno = curl_errno($ch); $curlError = curl_error($ch); if ($curlErrno == CURLE_COULDNT_RESOLVE_HOST) { $this->form_validation->set_message("url_check", "The host does not exist! Please verify the domain."); } else if ($curlErrno == CURLE_COULDNT_CONNECT) { $this->form_validation->set_message("url_check", "Server refused the connection! The URL might be unreachable."); } else if ($curlErrno == CURLE_OPERATION_TIMEDOUT) { $this->form_validation->set_message("url_check", "Connection timed out! Please try again later."); } else { $this->form_validation->set_message("url_check", "Could not connect to the URL: {$curlError}"); } return FALSE; }
二、构建可靠的URL格式验证与有效性检查逻辑
要确保用户输入的URL合法且有效,建议遵循格式验证→协议补全→有效性验证的流程:
1. 先验证URL格式合法性
不要自己写正则表达式,PHP内置的filter_var()函数配合FILTER_VALIDATE_URL过滤器是最可靠的方式,能覆盖所有标准URL格式的校验。
另外要注意:很多用户输入URL时会省略http://或https://协议头,这种情况下curl无法正确发起请求,所以我们要先自动补全协议头。
示例代码:
$inputUrl = $html_brand; // 自动补全协议头(如果用户没输入的话) if (!preg_match("/^https?:\/\//i", $inputUrl)) { $inputUrl = "https://" . $inputUrl; } // 验证格式合法性 if (!filter_var($inputUrl, FILTER_VALIDATE_URL)) { $this->form_validation->set_message("url_check", "Invalid URL format! Please enter a URL starting with http:// or https://"); return FALSE; }
2. 再验证URL的真实有效性
结合curl的执行结果、错误码和HTTP状态码来综合判断:
- 如果
curl_exec($ch)返回false,根据curl_errno()判断是DNS失败、连接拒绝还是超时; - 如果
curl_exec($ch)成功,再检查HTTP状态码:2xx表示请求成功,4xx/5xx表示页面或服务器存在错误,3xx重定向会被CURLOPT_FOLLOWLOCATION自动处理,最终返回重定向后的状态码。
3. 完整的整合代码
把以上逻辑整合到你的表单验证函数中:
function url_check($html_brand) { // 步骤1:自动补全协议头 if (!preg_match("/^https?:\/\//i", $html_brand)) { $html_brand = "https://" . $html_brand; } // 步骤2:验证URL格式 if (!filter_var($html_brand, FILTER_VALIDATE_URL)) { $this->form_validation->set_message("url_check", "Invalid URL format! Please enter a valid URL starting with http:// or https://"); return FALSE; } // 步骤3:初始化curl并设置选项 $ch = curl_init(); $options = array( CURLOPT_URL => $html_brand, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => true, CURLOPT_FOLLOWLOCATION => true, CURLOPT_AUTOREFERER => true, CURLOPT_CONNECTTIMEOUT => 10, // 缩短超时时间,提升用户体验 CURLOPT_TIMEOUT => 10, CURLOPT_MAXREDIRS => 10, CURLOPT_SSL_VERIFYPEER => true, // 生产环境建议开启SSL验证 CURLOPT_SSL_VERIFYHOST => 2, // 生产环境设为2,严格验证SSL证书 ); curl_setopt_array($ch, $options); // 步骤4:执行请求并获取结果 $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $curlErrno = curl_errno($ch); $curlError = curl_error($ch); // 步骤5:判断结果 $result = TRUE; if ($response === false) { switch ($curlErrno) { case CURLE_COULDNT_RESOLVE_HOST: $msg = "The host does not exist! Please check the domain."; break; case CURLE_COULDNT_CONNECT: $msg = "Server refused the connection! The URL might be unreachable."; break; case CURLE_OPERATION_TIMEDOUT: $msg = "Connection timed out! Please try again later."; break; default: $msg = "Could not connect to the URL: {$curlError}"; break; } $this->form_validation->set_message("url_check", $msg); $result = FALSE; } else { if ($httpCode >= 400) { if ($httpCode == 404) { $msg = "URL is well-formed but the page does not exist (404 error)!"); } else { $msg = "URL is unreachable, returned HTTP status code: {$httpCode}"; } $this->form_validation->set_message("url_check", $msg); $result = FALSE; } } curl_close($ch); return $result; }
内容的提问来源于stack exchange,提问作者Pratyush Deb
相关产品推荐
相关产品推荐

