PHP遍历数组时unset返回404的URL无效问题求助
解决遍历数组移除404 URL后数组未更新的问题
先理清楚你的场景:你有一个包含两个URL的数组,其中第一个返回404状态码,第二个返回301状态码,想用response函数判断状态码后移除404的URL,但执行var_dump($redirects)后发现数组还是保留两个元素——问题大概率出在foreach的遍历逻辑和unset的用法上!
先还原你的基础代码:
// 你的URL数组 $redirects = [ "http://www.myricacity.com//outline", "http://www.cigr.co.jp/pj/shinchiku/A80297//outline" ]; // 获取HTTP状态码的函数 function response($url){ $ch = curl_init($url); curl_setopt($ch, CURLOPT_HEADER, true); // curl_setopt($ch, CURLOPT_NOBODY, true); // curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); curl_setopt($ch, CURLOPT_TIMEOUT,10); $output = curl_exec($ch); $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); return $httpcode; }
问题根源
你大概率是在foreach里只遍历了数组的值,没有拿到对应的键,导致执行的unset($url)只是销毁了循环中的临时变量,完全没改动原数组$redirects。比如错误的写法通常是这样:
$dumpLinks = []; foreach($redirects as $url) { // 只拿到值,没拿到对应的数组键 $code = response($url); if($code == 404 && !in_array($url, $dumpLinks)) { $dumpLinks[] = $url; unset($url); // 这里销毁的是临时变量$url,不是原数组里的元素! } }
正确解决方案
方案1:遍历键值对,通过键删除原数组元素
这是最稳妥的方式,明确操作原数组的对应索引:
$dumpLinks = []; foreach($redirects as $key => $url) { // 同时拿到数组键$key和对应值$url $httpcode = response($url); if($httpcode == 404 && !in_array($url, $dumpLinks)) { $dumpLinks[] = $url; unset($redirects[$key]); // 通过键精准删除原数组的对应元素 } } var_dump($redirects); // 现在只会保留返回301的URL
方案2:用array_filter过滤数组(更简洁)
直接用数组过滤函数,一步完成状态判断和元素移除,代码更清爽:
$dumpLinks = []; $redirects = array_filter($redirects, function($url) use (&$dumpLinks) { $httpcode = response($url); if($httpcode == 404) { $dumpLinks[] = $url; return false; // 返回false表示过滤掉该元素 } return true; // 返回true表示保留该元素 }); var_dump($redirects);
额外优化:提升response函数效率
你的response函数里注释了CURLOPT_NOBODY和CURLOPT_RETURNTRANSFER,这会导致curl下载整个响应体,浪费带宽和时间。建议打开这两个选项,只获取响应头即可:
function response($url){ $ch = curl_init($url); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_NOBODY, true); // 只请求响应头,不下载正文 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 把响应内容返回给变量,不直接输出 curl_setopt($ch, CURLOPT_TIMEOUT, 10); curl_exec($ch); // 因为设置了RETURNTRANSFER,这里可以不用接收返回值 $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); return $httpcode; }
内容的提问来源于stack exchange,提问作者user10828115
相关产品推荐
相关产品推荐

