PHP 发起 HTTP 请求的 6 种核心方法详解
在 PHP Web 开发中,与第三方 API 交互或抓取网页数据时,发起 HTTP 请求是基础且核心的操作。本文将梳理并详细解析 PHP 中实现 GET 和 POST 请求的六种主流方法,包括原生函数 `file_get_contents`、`fopen`、`fsockopen` 以及功能最强的 `cURL` 库,助您快速掌握各种方案的代码实现与注意事项。
使用 file_get_contents 发起请求
file_get_contents 是读取文件内容最简单的函数,配合 PHP 的“流包装器”(Stream Wrappers)和上下文(Context),可以直接用于发起网络请求。它无需安装额外扩展,但在性能复杂度和安全性上不如 cURL。
第1步:使用 file_get_contents 发起 GET 请求
目的:获取指定 URL 的内容。
- 入口:直接使用函数调用。
- 动作:将 URL 传入函数即可。
<?php
$url = 'https://www.jb51.net/';
// 注意:如果服务器禁用了 allow_url_fopen,此法将无效
$html = file_get_contents($url);
echo $html;
?>
第2步:使用 file_get_contents 发起 POST 请求
目的:向目标地址提交表单数据。
- 入口:构建数据数组,生成查询字符串。
- 动作:配置
http类型的上下文参数,包含 Method、Header 和 Content。 - 重要参数:
method设为 POST,header需声明Content-type,content为编码后的数据。
<?php
$data = array('foo' => 'bar');
$data = http_build_query($data);
$opts = array(
'http' => array (
'method' => 'POST',
'header'=> "Content-type: application/x-www-form-urlencoded\r\n" .
"Content-Length: " . strlen($data) . "\r\n",
'content' => $data
)
);
$context = stream_context_create($opts);
// 第二个参数 false 表示不引入父级上下文
$html = file_get_contents('http://localhost/e/admin/test.html', false, $context);
echo $html;
?>
使用 fopen 打开网络连接
fopen 通常用于本地文件,但同样支持远程 URL。由于它是流式读取,对于大数据量或需要精确控制缓冲的场景有一定参考价值,但效率通常低于直接返回字符串的方法。
第3步:使用 fopen 以 GET 方式获取内容
目的:逐行读取远程内容。
- 入口:
fopen($url, 'r')。 - 动作:通过循环
feof判断是否结束,利用fgets读取每一行。 - 完成状态:内存中拼接出完整 Body 后,必须手动
fclose释放资源。
<?php
$fp = fopen($url, 'r');
stream_get_meta_data($fp); // 获取流元数据
$result = ''; // 初始化结果变量
while(!feof($fp)) {
$result .= fgets($fp, 1024);
}
echo "url body: $result";
fclose($fp);
?>
使用 fsockopen 进行底层 Socket 通信
fsockopen 提供了更底层的网络连接能力,适用于需要完全自定义 HTTP 协议头部、Cookie 或处理非标准响应的场景。前置条件:必须在 php.ini 中开启 allow_url_fopen 选项。
第4步:封装 fsockopen 以实现 GET 请求
目的:获取完整的 HTTP 响应(包括 Header 和 Body),并进行解析。
- 入口:编写辅助函数解析 URL。
- 动作:连接 Socket,手动组装 HTTP/1.1 GET 请求包(含 Host、Connection: Close)。
- 重要参数:超时时间设为 30秒,自动处理默认端口 80。
<?php
function get_url ($url, $cookie = false) {
$url = parse_url($url);
$query = $url["path"] . "?" . $url["query"];
echo "Query:" . $query;
// 建立连接
$fp = fsockopen($url["host"], isset($url["port"]) ? $url["port"] : 80, $errno, $errstr, 30);
if (!$fp) {
return false;
} else {
// 组装请求头
$request = "GET $query HTTP/1.1\r\n";
$request .= "Host: $url[host]\r\n";
$request .= "Connection: Close\r\n";
if($cookie) $request .= "Cookie: $cookie\r\n";
$request .= "\r\n";
fwrite($fp, $request);
$result = '';
while(!@feof($fp)) {
$result .= @fgets($fp, 1024);
}
fclose($fp);
return $result;
}
}
// 提取纯 HTML Body
function GetUrlHTML($url, $cookie = false) {
$rowdata = get_url($url, $cookie);
if($rowdata) {
// 找到空的 CRLF 之后即为 Body
$body = stristr($rowdata, "\r\n\r\n");
$body = substr($body, 4, strlen($body));
return $body;
}
return false;
}
?>
第5步:封装 fsockopen 以实现 POST 请求
目的:模拟表单 POST 提交,获取服务器原始响应。
- 入口:定义
HTTP_Post函数。 - 动作:对数据进行 URL Encode 并拼接为 Query String 格式;手动构造 POST 请求头,包含 Content-length 和 Referer。
- 风险提示:该示例未处理 SSL (HTTPS),仅适用于 HTTP 协议。若需 HTTPS,建议使用 Stream Context 或 cURL。
<?php
function HTTP_Post($URL, $data, $cookie, $referrer = "") {
// 解析 URL
$URL_Info = parse_url($URL);
// 设置默认 Referrer
if($referrer == "") $referrer = "111";
// 格式化数据
foreach($data as $key => $value) {
$values[] = "$key=" . urlencode($value);
}
$data_string = implode("&", $values);
// 确定端口
if(!isset($URL_Info["port"])) $URL_Info["port"] = 80;
// 组装 POST 请求
$request = "POST " . $URL_Info["path"] . " HTTP/1.1\r\n";
$request .= "Host: " . $URL_Info["host"] . "\r\n";
$request .= "Referer: $referrer\r\n";
$request .= "Content-type: application/x-www-form-urlencoded\r\n";
$request .= "Content-length: " . strlen($data_string) . "\r\n";
$request .= "Connection: close\r\n";
$request .= "Cookie: $cookie\r\n";
$request .= "\r\n";
$request .= $data_string . "\r\n";
$fp = fsockopen($URL_Info["host"], $URL_Info["port"]);
fputs($fp, $request);
$result = '';
while(!feof($fp)) {
$result .= fgets($fp, 1024);
}
fclose($fp);
return $result;
}
?>
使用 cURL 库发起请求(推荐)
cURL 是 PHP 中最强大、最常用的 HTTP 客户端扩展。它支持重定向、Cookies、SSL、Proxy、上传文件等几乎所有 HTTP 特性,且拥有极佳的稳定性和错误处理机制。前置条件:请确认 php.ini 中已启用 extension=curl。
第6步:使用 cURL 发起 GET 请求
目的:安全、高效地获取资源并处理连接超时。
- 入口:
curl_init()。 - 动作:配置
CURLOPT_URL,设置CURLOPT_RETURNTRANSFER为 true 以便获取返回值而非直接输出,设置超时时间。 - 完成状态:执行
curl_exec获取内容,最后用curl_close关闭句柄释放资源。
<?php
$ch = curl_init();
$timeout = 5;
curl_setopt($ch, CURLOPT_URL, 'https://www.jb51.net/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$file_contents = curl_exec($ch);
curl_close($ch);
echo $file_contents;
?>
总结与建议
综上所述,虽然 file_get_contents 和 fsockopen 无需外部依赖,但前者在处理复杂请求时配置繁琐且不可见性较强(如无法轻易获取 HTTP 状态码),后者则需要编写大量样板代码维护 HTTP 协议细节。在现代 PHP 开发中,**cURL** 凭借其完善的 API 和对各种异常情况的处理能力,是首选方案。若您使用的是 PHP 5.6+ 版本,除了上述基础方法外,也可以考虑引入 Guzzle 等现代 HTTP 客户端库来进一步简化开发流程。
以上就是 PHP 发起 HTTP 请求的 6 种核心方法的详细内容,更多关于 PHP 网络编程的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













