PHP HTTP 请求的几种方式

php函数 file_get_contents,fsockopen,curl,fopen实现的HTTP GET/POST请求.

接着上篇的 HTTP 简介,直接上php实现代码:

file_get_contents实现POST请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$data = array("name" => 'xiie',"content" => 'test');
$data = http_build_query($data);
$opts = array(
'http'=>array(
'method'=>"POST",
'timeout'=>60,
'header'=>"Content-type: application/x-www-form-urlencoded\r\n".
"Content-length:".strlen($data)."\r\n" .
"Cookie: foo=bar\r\n" .
"\r\n",
'content' => $data,
)
);
$cxContext = stream_context_create($opts);
$sFile = file_get_contents("http://localhost/tmp.php", false, $cxContext);
echo $sFile;

file_get_contents实现GET请求(带重试)

1
2
$cnt=0;
while($cnt < 3 && ($str=@file_get_contents("http://localhost/tmp.php"))===FALSE) $cnt++;

fopen实现GET请求

1
2
3
4
5
6
7
$fp = fopen("http://www.jb51.net/article/51974.htm", 'r');
stream_get_meta_data($fp);
while(!feof($fp)) {
$result .= fgets($fp, 1024);
}
echo $result;
fclose($fp);

fsockopen实现GET请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
sock_get('http://localhost/tmp.php?name=xiie');
function sock_get($url)
{
$info = parse_url($url);
$fp = fsockopen($info["host"], 80, $errno, $errstr, 3);
$head = "GET ".$info['path']."?".$info["query"]." HTTP/1.0\r\n";
$head .= "Host: ".$info['host']."\r\n";
$head .= "\r\n";
$write = fputs($fp, $head);
while (!feof($fp))
{
$line = fread($fp,4096);
echo $line;
}
}

fsockopen实现POST请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
sock_post('http://localhost/tmp.php',"name=xiie");
function sock_post($url, $query)
{
$info = parse_url($url);
$fp = fsockopen($info["host"], 80, $errno, $errstr, 3);
$head = "POST ".$info['path']."?".$info["query"]." HTTP/1.0\r\n";
$head .= "Host: ".$info['host']."\r\n";
$head .= "Referer: http://".$info['host'].$info['path']."\r\n";
$head .= "Content-type: application/x-www-form-urlencoded\r\n";
$head .= "Content-Length: ".strlen(trim($query))."\r\n";
$head .= "\r\n";
$head .= trim($query);
$write = fputs($fp, $head);
while (!feof($fp))
{
$line = fread($fp,4096);
echo $line;
}
}

curl实现GET请求

1
2
3
4
5
6
7
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.jb51.net");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$output = curl_exec($ch);
curl_close($ch);
print_r($output);

curl实现POST请求

1
2
3
4
5
6
7
8
9
10
$url = "http://localhost/tmp.php";
$post_data = array ("username" => "bob","key" => "12345");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
$output = curl_exec($ch);
curl_close($ch);
print_r($output);

比较

  • socket更底层,可以设置基于UDP或是TCP协议去交互; file_get_contents 和 curl 能干的,socket都能干; socket能干的,curl 就不一定能干了.
  • curl 效率比file_get_contents()和fsockopen()高一些,原因是CURL会自动对DNS信息进行缓存.
  • fsockopen 返回的是没有处理过的数据,包括数据的长度,数据内容和数据的结束符; file_get_contents 和 curl是处理后的内容.
  • fsockopen,file_get_contents函数会受到php.ini文件中allow_url_open选项配置的影响.如果该配置关闭了,则该函数也就失效了;而curl不受该配置的影响.
  • file_get_contents()函数获取https链接内容的时候,需要php 中mod_ssl的支持(或安装opensll).
  • 结论就是,curl 效率及稳定都比 file_get_contents() 要好,fsockopen 也很强大,但是比较偏底层.

参考链接: