PHP模拟http请求
Phpclient 库
当服务器后台准备向另一台服务器发送请求时,我们可以使用使用php模拟http请求。方法如下:
1、使用httpclient库的方式;
2、用socket方式。
一、使用httpclient类库
a)使用httpclient类库,可以去官方下载最新的类库,官方地址为:http://scripts.incutio.com/httpclient/index.php
b) 静态方法获取网页:
$pageContents = HttpClient::quickGet(http://example.com/)
c) Get方法获取:
$client = new HttpClient(example.com);
if (!$client->get(/)) {
die(An error occurred: .$client->getError());
}
$pageContents = $client->getContent();
d) 带调试的Get方法获取
$client
= new HttpClient('example.com');
$client->setDebug(true);
if (!$client->get('/')) {
die('An error occurred:
'.$client->getError());
}
$pageContents
= $client->getContent();
e) 带自动转向的Get方法
f) 检查页面是否存在
$client
= new HttpClient('example.com');
$client->setDebug(true);
if (!$client->get('/thispagedoesnotexist')) {
die('An error occurred:
'.$client->getError());
}
if ($client->getStatus() == '404') {
echo 'Page does not exist!';
}
$pageContents = $client->getContent();
g) 伪造客户端
$client
= new HttpClient('example.com');
$client->setDebug(true);
$client->setUserAgent('Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US;
rv:1.3a) Gecko/20021207');
if (!$client->get('/')) {
die('An error occurred:
'.$client->getError());
}
$pageContents = $client->getContent();
h) 登录验证并请求一个网页
$client
= new HttpClient('example.com');
$client->post('/login.php', array(
'username' => 'Simon',
'password' => 'ducks'
));
if (!$client->get('/private.php')) {
die('An error occurred:
'.$client->getError());
}
$pageContents = $client->getContent();
i) 输出头信息
$client
= new HttpClient('example.com');
if (!$client->get('/')) {
die('An error occurred:
'.$client->getError());
}
print_r($client->getHeaders());
j) HTTP授权
$client
= new HttpClient('example.com');
$client->setAuthorization('Username', 'Password');
if (!$client->get('/')) {
die('An error occurred:
'.$client->getError());
}
$pageContents = $client->getContent();
k) 设置一个域内重定向最多次数
$client = new HttpClient('www.amazon.com');
$client->setDebug(true);
$client->setMaxRedirects(3);
$client->get('/');
二、用socket方式
Socket函数:打开网络的 Socket 链接
语法: resuce fsockopen(string hostname, int port, int [errno], string [errstr], int [timeout]);
目前这个函数提供两个Socket资料流界面,分别为 Internet 用的 AF_INET 及 Unix 用的AF_UNIX。在 Internet 中,参数 hostname及port分别代表网址及端口号。在 UNIX 中,参数hostname表示到socket的路径,port配置为0。timeout可省略表示多久没有连上就中断。该函数返回文件指针,供文件函数使用,包括 fgets()、fgetss()、fputs()、fclose()、feof()。参数errno 及 errstr 可省略,做错误处理使用。该函数使用阻塞模式 (blocking mode) 处理,可用 set_socket_blocking() 转换成无阻塞模式。
function getIdcWebHtml($url){
$conn_host='172.27.28.234';
$conn_port='8080';
$query = "GET $url HTTP/1.0\r\n".
//"HOST:$host:$port\r\n".
"User-agent:PHP/class http 0.1\r\n".
"\r\n";
$fp = fsockopen($conn_host,$conn_port);
if(!$fp){
return false;
}else{
fputs($fp,$query);
while(!feof($fp)) {
$cc .= fgets($fp);
}
fclose($fp);
$content=trimHeader($cc);
return $content;
}
}
最后看了下httpclient 库函数,其实也是通过fsocketopen函数进行操作的,只是将这一系列的操作进行了很好的封装处理。
基于此,使用了httpclient方式做了php对抽奖接口的调用,php部署在chong.qq.com/php/raffle.php 在服务器10.6.206.52上。
调用方法如下:
public function index() {
$uin = "644832017";
$host = 'party.paipai.com';
$path = 'http://party.paipai.com/cgi-bin/cxpl_drawing';j
$g_tk = 937585002;
//抽奖接口IP列表
$ips= array('10.128.2.160','10.128.2.197',
'10.128.2.198','10.128.2.221',
'10.128.3.23','10.128.3.24',
'10.128.3.68','172.23.131.153');
@$ip = $ips[rand(0,count($ips)-1)];
$port = 80;
$cookies = array();
$_COOKIE['uin'] = $uin;
//对于2亿以上号码,拍拍cookie中uin字段以字母o开头,会导致登录态失效。
//因此可对cookie中任何uin都去掉首字母o,在拍拍侧是有效的。
foreach($_COOKIE as $key => $value){
$cookies[$key] = $value;
}
$lottery = new HttpClient($host,$port);
$lottery->setDebug(true);
//var_dump($lottery);
$lottery->setCookies($cookies);
$lottery->ip = $ip;
$data = array('active' => 'comment0906','g_tk' => $g_tk, 't' => rand());
//发送GET请求,判断请求是否失败
$ret = $lottery->get($path,$data);
var_dump($lottery);
//var_dump($lottery->getContent());
if($ret){
$response = $lottery->getContent();
echo $response;
}else{
echo "fail";
}
}
请求成功,返回回调函数afterRaffle。