php curl请求信息和返回信息

本文介绍如何使用curl工具抓取包含重定向的网页,并通过递归函数获取最终实际请求的URL地址。

在用curl抓取网页内容的时候,经常要知道,网页返回的请求头信息,和请求的相关信息,特别是在请求过程中存在重定向的时候获取请求返回头信息对分析请求内容很有帮助


下面就是一个请求中存在重定向的例子,我们的目的是要获取最终实际请求的url地址

$url='http://www.appchina.com/market/r/489267/com.appshare.android.ilisten.vapk?c=aplus.direct&uid=gAJ9cQEu1TlyZxsXN-aB4RaanvFL6t6Bj-vj0rIBs&p=aplus.detail&m=redirect';

$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
//curl_setopt($ch, CURLOPT_POST, 1);
//curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HEADER, 1);//返回response头部信息
curl_setopt($ch, CURLOPT_NOBODY, 1);//不返回response body内容
//curl_setopt($ch, CURLOPT_MAXREDIRS, 1);//设置请求最多重定向的次数
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);//不直接输出response
curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);//如果返回的response 头部中存在Location值,就会递归请求
$content=curl_exec($ch);
$rinfo=curl_getinfo($ch);

echo $content,"</br>";
echo "<hr>";
print_r($rinfo);

下面是输出的结果

HTTP/1.1 200 OKServer: nginxDate: Sat, 22 Dec 2012 06:17:44 GMTContent-Type: application/vnd.android.package-archiveConnection: closeLast-Modified: Mon, 03 Dec 2012 16:00:00 GMTExpires: Tue, 03 Dec 2013 16:00:00 GMTCache-Control: max-age=31536000Content-Length: 2142149

Array( [url] => http://www.d.appchina.com/McDonald/r/489267/com.appshare.android.ilisten.vapk?c=aplus.direct&uid=gAJ9cQEu1TlyZxsXN-aB4RaanvFL6t6Bj-vj0rIBs&p=aplus.detail&m=redirect [content_type] => application/vnd.android.package-archive [http_code] => 200 [header_size] => 289 [request_size] => 196 [filetime] => -1 [ssl_verify_result] => 0 [redirect_count] => 0 [total_time] => 0.171621 [namelookup_time] => 0.135256 [connect_time] => 0.152913 [pretransfer_time] => 0.152916 [size_upload] => 0 [size_download] => 0 [speed_download] => 0 [speed_upload] => 0 [download_content_length] => 2142149 [upload_content_length] => 0 [starttransfer_time] => 0.171582 [redirect_time] => 0 [certinfo] => Array ( )) 


可以看到,经过递归请求后最终得到一个200的response,但是这中方式不能得到最后一次请求的url,也就是最终实际请求的url,要想得到这个url就需要递归的分析每次请求返回的response

下面是我写的一个获取最后一次请求url的递归函数

$url='http://www.appchina.com/market/r/489267/com.appshare.android.ilisten.vapk?c=aplus.direct&uid=gAJ9cQEu1TlyZxsXN-aB4RaanvFL6t6Bj-vj0rIBs&p=aplus.detail&m=redirect';
$realUrl=getRedirectLocation($url);

echo "</br>--->",$realUrl;

function getRedirectLocation($url){
	
	$realUrl=$url;
	echo $url,"</br>";
	$ch=curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_HEADER, 1);curl_setopt($ch, CURLOPT_TIMEOUT, 3);//设置curl执行时间不超过3秒
	//curl_setopt($ch, CURLOPT_NOBODY, 1);//这行不能要,如果添上,那么在遇到302重定向的时候就会得不到真正的请求url
	curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
	$content=curl_exec($ch);
	//echo $content;
	$rinfo=curl_getinfo($ch);
	$matches=array();
	if(preg_match('/Location:\s+?(.+?)\s+?/', $content,$matches)){
		//echo $matches[1],"</br>";
		unset($content);
		$realUrl=getRedirectLocation($matches[1]);
	}
	if(isset($content)){
		unset($content);
	}
	return $realUrl;
}


<think>我们被要求使用PHPcurl功能进行信息请求与获取。根据提供的引用,我们可以整合相关信息来构建一个完整的示例。引用[1]介绍了PHP中使用CURL实现GETPOST请求,并提到CURL是一个功能强大的库,可以简单有效地抓取网页。引用[2]提供了一些函数,但我们主要关注curl部分。引用[3]则提到了在抓取https请求时可能遇到的证书问题。我们的目标是:1.使用PHPcurl发起GET请求(也可以扩展到POST请求)2.处理可能遇到的https证书问题3.获取请求结果步骤:1.初始化curl会话:curl_init()2.设置curl选项,包括URL,是否返回传输内容,设置头信息,以及SSL相关设置等3.执行curl请求curl_exec()4.检查错误,处理返回结果5.关闭curl会话:curl_close()对于https请求,可能会遇到证书验证失败的问题(如引用[3]所述),我们可以通过设置CURLOPT_SSL_VERIFYPEERCURLOPT_SSL_VERIFYHOST为false来跳过验证(但在生产环境中不推荐,因为不安全,这里仅用于测试或目标服务器证书有问题时)。下面是一个基本的函数,用于实现GET请求,并考虑到https的情况:```phpfunctioncurl_get($url,$https=false){$ch=curl_init();curl_setopt($ch,CURLOPT_URL,$url);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);//要求返回结果为字符串,而不是直接输出if($https){//跳过SSL证书验证curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);}$output=curl_exec($ch);if($output===false){//请求失败,输出错误信息echo'cURLError:'.curl_error($ch);}curl_close($ch);return$output;}```如果需要发送POST请求,我们可以这样写:```phpfunctioncurl_post($url,$post_data,$https=false){$ch=curl_init();curl_setopt($ch,CURLOPT_URL,$url);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);curl_setopt($ch,CURLOPT_POST,1);//发送POST请求curl_setopt($ch,CURLOPT_POSTFIELDS,$post_data);//POST数据if($https){curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);}$output=curl_exec($ch);if($output===false){echo'cURLError:'.curl_error($ch);}curl_close($ch);return$output;}```注意:1.在正式环境中,我们应该避免跳过SSL验证,因为这可能导致中间人攻击。正确的方式是设置正确的证书路径(CURLOPT_CAINFO)或使用系统证书。2.根据引用[2],如果我们获取的数据需要进行安全性检查,比如防SQL注入,那么我们在处理返回的数据插入数据库前应该对数据进行过滤转义,或者使用预处理语句。下面是一个更完善的GET请求示例,包括设置超时、用户代理等:```phpfunctioncurl_get_advanced($url,$https=false,$timeout=30){$ch=curl_init();curl_setopt($ch,CURLOPT_URL,$url);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout);//连接超时curl_setopt($ch,CURLOPT_TIMEOUT,$timeout);//执行超时curl_setopt($ch,CURLOPT_USERAGENT,'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/58.0.3029.110Safari/537.3');//模拟用户代理if($https){curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);}$output=curl_exec($ch);if($output===false){$error=curl_error($ch);curl_close($ch);thrownewException('cURLError:'.$error);}$httpCode=curl_getinfo($ch,CURLINFO_HTTP_CODE);curl_close($ch);returnarray('body'=>$output,'http_code'=>$httpCode);}```这样我们就可以通过调用这些函数来实现信息请求与获取。举例使用:1.GET请求:$result=curl_get('http://example.com');//如果是https:$result=curl_get('https://example.com',true);2.POST请求:$post_data=array('key1'=>'value1','key2'=>'value2');$result=curl_post('http://example.com/post',$post_data);//或者https:$result=curl_post('https://example.com/post',$post_data,true);如果需要处理更复杂的情况(如设置头信息、cookie等),可以进一步设置curl选项。注意:上面的函数只是示例,实际使用时可能需要根据具体需求调整。</think> 下面我将详细介绍如何使用PHP cURL实现信息请求与获取,包括GETPOST请求的实现方法、HTTPS证书问题解决及安全注意事项。 ### PHP cURL 基本使用流程 ```php // 初始化cURL会话 $ch = curl_init(); // 设置请求URL curl_setopt($ch, CURLOPT_URL, "https://api.example.com/data"); // 设置返回结果不直接输出 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 执行请求并获取返回内容 $response = curl_exec($ch); // 检查错误 if(curl_errno($ch)) { echo 'cURL Error: ' . curl_error($ch); } // 获取HTTP状态码 $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); // 关闭会话 curl_close($ch); // 处理响应数据 if ($httpCode == 200) { echo "获取成功:" . $response; } else { echo "请求失败,状态码:" . $httpCode; } ``` ### 实现GET请求 ```php function curlGet($url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 解决HTTPS证书问题(不验证证书) curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $response = curl_exec($ch); curl_close($ch); return $response; } // 使用示例 $data = curlGet("https://api.example.com/users?id=123"); ``` ### 实现POST请求 ```php function curlPost($url, $postData) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 安全设置(处理SSL证书) curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); $response = curl_exec($ch); curl_close($ch); return $response; } // 使用示例 $postData = http_build_query([ 'username' => 'john', 'password' => 'secret123' ]); $result = curlPost("https://api.example.com/login", $postData); ``` ### HTTPS证书问题解决 当遇到`SSL certificate problem`错误时(引用[3]),可通过以下方法解决: 1. **临时禁用验证(测试环境)**: ```php curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); ``` 2. **正式环境解决方案**: ```php // 指定CA证书路径 curl_setopt($ch, CURLOPT_CAINFO, '/path/to/cacert.pem'); curl_setopt($ch, CURLOPT_CAPATH, '/path/to/cacert.pem'); ``` > 从 [curl.haxx.se/ca/cacert.pem](https://curl.haxx.se/ca/cacert.pem) 下载最新CA证书包 ### 安全注意事项 1. **防SQL注入(引用[2])**: ```php function sanitizeInput($input) { $dangerousPatterns = '/(select|insert|update|delete|union|into|load_file|outfile|\-\-)/i'; return preg_match($dangerousPatterns, $input) ? null : $input; } ``` 2. **参数过滤**: ```php $safeUrl = filter_var($userInputUrl, FILTER_SANITIZE_URL); ``` ### 高级功能 ```php // 设置请求头 $headers = [ 'Authorization: Bearer token123', 'Content-Type: application/json' ]; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); // 获取详细调试信息 curl_setopt($ch, CURLOPT_VERBOSE, true); $verbose = fopen('php://temp', 'w+'); curl_setopt($ch, CURLOPT_STDERR, $verbose); // 文件下载 curl_setopt($ch, CURLOPT_FILE, fopen('download.zip', 'w')); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值