PHP检测远程文件存在失效,求可识别无效URL的有效函数
解决方案:针对德国数学奥林匹克网站的文件存在性检测函数
目标网站对HEAD请求的处理逻辑特殊——无论请求的文件是否存在,都会返回200 OK状态码,这导致仅通过状态码判断的方法完全失效。需要结合响应的内容类型、内容长度或实际内容特征来做准确判断。
以下是两种可行的PHP实现方案:
方法1:通过CURL检查响应头特征
该方法优先验证响应的Content-Type是否为PDF类型,同时结合内容长度过滤(无效请求返回的错误页长度远小于正常PDF文件):
function fileExistsOnMO($url) { $ch = curl_init($url); // 仅获取响应头,禁止输出内容 curl_setopt($ch, CURLOPT_NOBODY, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 自动跟随重定向 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 设置请求超时时间 curl_setopt($ch, CURLOPT_TIMEOUT, 10); curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); $contentLength = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD); curl_close($ch); // 多条件校验:状态码200 + 正确PDF类型 + 内容长度符合正常PDF最小范围 return $httpCode === 200 && strpos($contentType, 'application/pdf') !== false && $contentLength > 1000; } // 测试调用 $url1 = "https://mathematik-olympiaden.de/moev/index.php?option=com_download&thema=a&format=raw&datei=A40051.pdf"; $url2 = "https://mathematik-olympiaden.de/moev/index.php?option=com_download&thema=a&format=raw&datei=A40061.pdf"; var_dump(fileExistsOnMO($url1)); // 输出 bool(false) var_dump(fileExistsOnMO($url2)); // 输出 bool(true)
方法2:验证PDF文件签名
如果网站返回的错误页被错误标记为PDF类型,可以进一步检查返回内容的前几个字节——标准PDF文件开头必然是%PDF-:
function fileExistsOnMO($url) { $ch = curl_init($url); // 仅获取前10字节内容,减少带宽消耗 curl_setopt($ch, CURLOPT_RANGE, '0-9'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_TIMEOUT, 10); $content = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); return $httpCode === 200 && str_starts_with($content, '%PDF-'); } // 测试调用 var_dump(fileExistsOnMO($url1)); // bool(false) var_dump(fileExistsOnMO($url2)); // bool(true)
原方法失效原因
目标网站的com_download组件在处理HEAD请求时,未正确校验文件存在性就直接返回200 OK,导致仅通过状态码无法区分有效与无效请求,必须结合响应的实际内容特征完成判断。
内容的提问来源于stack exchange,提问作者Malte
相关产品推荐
相关产品推荐

