PHP fsockopen 模拟 POST/GET 请求实战

夏知夏
夏知夏
发布时间:2026-10-13| 4人浏览过
原创

在 PHP 环境中,除了 cURL 之外,fsockopen 提供了一种更底层的方案来模拟 HTTP 客户端。本指南将演示如何构建标准的 HTTP 请求包,以向指定 URL 提交 GET 查询参数或 POST 表单数据,并接收服务器响应。

准备条件与原理分析

fsockopen 基于 TCP/IP 建立连接。要成功发起 HTTP 请求,必须严格按照 HTTP/1.1 协议规范拼接报文:

  • GET 请求:参数直接追加至 URL Query String 中。
  • POST 请求:参数需放入 Request Body,并在 Header 中声明 Content-Length 及 Content-Type: application/x-www-form-urlencoded。

第 1 步:编写 GET 请求函数

目的:构建 GET 头部并获取响应。
入口:目标 URL 字符串及关联的查询数组。

$arr = array(
  'user' => 'test',
  'password' => ''
);

// 调用示例
sock_get('http://example.com/api', $arr); 

function sock_get($url, $query = array()) {
  // 1. 解析 URL 结构
  $info = parse_url($url);
  // 2. 提取端口号,默认为 80
  $port = isset($info['port']) ? $info['port'] : 80;
  
  // 3. 组合查询字符串,注意避免重复参数
  $query_str = http_build_query($query);
  if (!empty($info["query"])) {
    $query_str .= '&' . $info["query"];
  }
  
  // 4. 建立网络连接
  $fp = fsockopen($info["host"], $port, $errno, $errstr, 30);
  if (!$fp) {
    return FALSE; // 连接失败返回假值
  }
  
  // 5. 组装 HTTP 头
  $head = "GET " . $info['path'] . "?" . trim($query_str) . " HTTP/1.1\r\n";
  $head .= "Host: " . $info['host'] . "\r\n";
  $head .= "Connection: Close\r\n"; // 明确关闭连接
  $head .= "\r\n";
  
  // 6. 发送请求头
  fputs($fp, $head);
  
  // 7. 循环读取响应内容
  $response = "";
  while(!feof($fp)) {
    $line = fgets($fp, 1024);
    $response .= $line;
  }
  
  fclose($fp);
  return $response;
}

第 2 步:编写 POST 请求函数

目的:构建 POST 头部与 Body,并提交表单数据。
重要参数:Body 长度必须准确匹配。
完成状态:完整输出 HTML 响应源码。

// 调用示例
sock_post('http://example.com/login', $arr); 

function sock_post($url, $data = array()) {
  // 1. 格式化数据为 form-encoded 格式
  $query = http_build_query($data);
  
  $info = parse_url($url);
  // 默认端口 80
  $fp = fsockopen($info["host"], 80, $errno, $errstr, 30);
  
  // 2. 组装复杂的请求头
  $head = "POST " . $info['path'] . (isset($info['query']) ? '?' . $info['query'] : '') . " HTTP/1.1\r\n";
  $head .= "Host: " . $info['host'] . "\r\n";
  $head .= "Content-type: application/x-www-form-urlencoded\r\n";
  $head .= "Content-Length: " . strlen($query) . "\r\n";
  $head .= "Connection: Close\r\n";
  $head .= "\r\n";
  
  // 3. 拼接 Body 并发送
  $head .= $query;
  fputs($fp, $head);
  
  // 4. 接收响应
  $response = "";
  while (!feof($fp)) {
    $line = fgets($fp, 1024);
    $response .= $line;
  }
  
  fclose($fp);
  return $response;
}

注意事项与排错

  • 超时设置:fsockopen 第四个参数为超时秒数,建议设置为非零值(如 30),防止脚本永久挂起。
  • 协议版本:HTTP/1.1 要求必须包含 Host 字段;若省略 Connection 头,部分服务端可能保持长连接导致读取阻塞。
  • 返回值差异:上述代码返回的是包含 HTTP 头部的完整响应体。若仅需正文,需过滤掉双换行符之前的头部信息。
以上就是利用 PHP fsockopen 模拟 POST/GET 传送数据的详细内容,更多关于 PHP Socket 网络通信的资料请关注本站其它相关文章!
相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。