codeigniter4需用http\client显式检查getstatuscode()(200–399为存活),禁用重定向、设5秒超时,并捕获dns/ssl等异常;批量检测应分批+并发落库,视图展示与检测分离,避免阻塞。

CodeIgniter 本身不提供友情链接自动检测或死链排查功能,必须自己实现 HTTP 状态码探测逻辑,且不能依赖框架内置的 curl 或 file_get_contents 封装(CI4 的 HTTP\Client 默认不校验响应状态码是否为 2xx/3xx)。
怎么用 CI4 的 HTTP\Client 检测链接是否存活
CI4 的 HTTP\Client 默认会把 4xx/5xx 响应也当作“成功请求”返回,直接调用 $client->get($url)->isOK() 不可靠——它只判断网络层是否通,不检查 HTTP 状态码语义。
- 必须显式检查
getStatusCode(),且只把 200–399 视为有效响应(301/302 跳转也算“链接可达”,除非业务明确要求最终落地页为 200) - 设置超时时间,避免单个链接卡住整个检测流程:
['timeout' => 5] - 禁用重定向自动跟随(
'allow_redirects' => false),否则 301 跳转后可能检测到的是跳转目标而非原始链接状态 - 示例片段:
$client = \Config\Services::curlrequest();
try {
$response = $client->get($url, ['timeout' => 5, 'allow_redirects' => false]);
$code = $response->getStatusCode();
$isAlive = ($code >= 200 && $code
<h3>怎么批量检测友情链接并避免阻塞</h3>
<p>一次查几十个外链,全同步执行会极慢。CI4 没有原生协程支持,但可用 <code>curl_multi</code> 手动并发,或退而求其次用队列 + 异步任务(如 CodeIgniter4-Queue 扩展)。</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2515" title="CodeIgniter 4.7.0"><img
src="https://img.php.cn/upload/manual/001/503/042/6a6b043218cde750.png" alt="CodeIgniter 4.7.0" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/gongju/2515" title="CodeIgniter 4.7.0" class="overflowclass">CodeIgniter 4.7.0</a>
<p class="overflowclass">CodeIgniter下载页提供 CodeIgniter 4.7.0 官方源码包,并整理框架安装、数据库配置与入门开发说明。</p>
</div>
<a rel="nofollow" href="/xiazai/gongju/2515" title="CodeIgniter 4.7.0" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
- 不推荐用
foreach+sleep()模拟“节流”,既不准又浪费资源 - 更实用的做法:把待检测链接写入数据库表(如
links_to_check),用命令行脚本(php spark link:check)分批拉取、并发检测、更新结果字段(status_code,last_checked,is_alive) - 注意 DNS 解析失败、连接被拒绝(cURL error 7)、SSL 证书过期等异常需单独捕获,不能只靠
getStatusCode()
为什么用 model 查询出来的友情链接在视图里显示为空
常见原因是控制器传给视图的数组键名和视图中实际使用的变量名不一致,比如模型返回了 $links,控制器却写成 $data['friend_links'] = $links;,而视图里直接写了 foreach ($links as $l) —— 这会导致 $links 未定义。
- 检查控制器中
return view('xxx', $data)的$data键名是否与视图中$xxx变量名完全对应 - CI4 中模型默认返回
array或Result对象,若用findAll()得到空数组,foreach不报错但不执行,容易误判为“没数据” - 调试时可在控制器加
log_message('debug', 'Links count: ' . count($links));,确认数据确实从 DB 拉出来了
死链检测结果怎么存、怎么展示才不拖慢后台
每次检测都实时查库+渲染页面,用户点一次“刷新检测”就卡 10 秒,体验极差。应该把检测动作和展示分离。
- 检测结果必须落库(哪怕只是临时表),不能只存在 session 或缓存里——否则页面刷新就丢
- 后台列表页只查
last_checked > DATE_SUB(NOW(), INTERVAL 1 HOUR)的记录,加索引在last_checked字段 - 前端用 AJAX 轮询检测任务状态(如
/admin/link/status?task_id=123),而不是让 PHP 请求一直挂着等所有链接查完
最易被忽略的一点:外链响应头里的 Content-Type 可能是 text/plain 或空,但 CI4 的 HTTP\Client 默认只对 text/html 做字符编码处理;如果目标站返回乱码 HTML,getStatusCode() 仍为 200,但后续解析标题或描述会失败——得先看 $response->getHeaderLine('content-type') 再决定是否继续。










