如何在PHP 8.2中从CURL响应获取Location URL
如何从CURL的301响应中提取Location URL?
我在PHP 8.2中使用CURL发送POST请求时,收到了301重定向响应,需要提取响应头里Location对应的URL。我的请求代码如下:
$arrPostFields = [ 'data_one' => $this->getDataOne, 'data_two' => $this->getDataTwo ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $this->apiUrl); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_POSTFIELDS, $arrPostFields); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_VERBOSE, 1); curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); $response = curl_exec($ch);
得到的响应内容:
HTTP/1.1 301 Moved Permanently Date: Tue, 02 May 2023 11:16:23 GMT Transfer-Encoding: chunked Connection: keep-alive Location: https://example.com/?url=aHffR0cgrHM6Ly9lY29tbWVyY2UudGJpYmFuay5yby9Mb2FuT3JpZ2luYXRpb25fQjJDUHJveHkvZWM/c2Vzc2lvbklkPTkyMTdiZTJkLTdjMjgtNDY1Yy1hMWYzLTNmNGNlNmJlZTMzZSZjdWx0dXJlPXJvLVJP&link2payid=f880864b-2cd5-4b95-bd53-ea65b0b46063 Server: Microsoft-IIS/10.0 X-Powered-By: ASP.NET
方案一:使用CURL内置方法(推荐)
直接通过CURL内置函数获取重定向URL,无需手动解析响应头。只需在CURL选项中添加CURLOPT_FOLLOWLOCATION设为false,再用curl_getinfo()提取:
$arrPostFields = [ 'data_one' => $this->getDataOne, 'data_two' => $this->getDataTwo ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $this->apiUrl); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_POSTFIELDS, $arrPostFields); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_VERBOSE, 1); curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // 禁止自动跟随重定向,保留301响应 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); $response = curl_exec($ch); // 直接获取Location头部的URL $locationUrl = curl_getinfo($ch, CURLINFO_REDIRECT_URL);
这种方法更可靠,避免了手动解析字符串可能出现的格式问题。
方案二:手动解析响应头字符串
如果无法修改CURL配置,可以拆分响应内容,手动提取Location字段:
// $response为curl_exec返回的完整响应内容 $headerLines = preg_split("/\r\n|\n|\r/", $response); $locationUrl = ''; foreach ($headerLines as $line) { if (str_contains($line, 'Location:')) { // 拆分后去除前后多余空格 $locationUrl = trim(explode('Location:', $line)[1]); break; // 找到后直接退出循环,提升效率 } }
通过正则拆分响应的每一行,定位到Location:所在行后拆分出URL,并用trim()去除可能存在的前后空格。
内容的提问来源于stack exchange,提问作者calin24
相关产品推荐
相关产品推荐

