php 7.3 模拟 post 并伪造 referer 的三种主流方式是:curl(最稳定,用 curlopt_referer 直接设置)、file_get_contents + stream_context_create(轻量,需手动在 header 中写入 referer 并精确计算 content-length)、fsockopen(底层可控,需完全手动构造含 referer 的 http 报文)。

PHP 7.3 模拟 POST 请求并伪造 Referer,核心是控制 HTTP 请求头中的 Referer 字段。有三种主流方式:cURL、file_get_contents + 流上下文、以及底层 socket(如 fsockopen)。其中 cURL 最稳定、可控性最强,推荐优先使用。
cURL 方式设置 Referer(最常用)
只需在 curl_setopt() 中添加 CURLOPT_REFERER 选项即可,无需手动拼接请求头。注意仍需正确配置 POST 基础参数和返回值捕获:
- 必须设
CURLOPT_RETURNTRANSFER => true,否则响应直接输出,无法获取结果 -
CURLOPT_POSTFIELDS可传数组(自动 URL 编码)或字符串;传数组时无需手动http_build_query() - 若目标接口校验 Referer 严格,确保伪造的地址协议、域名、路径格式合法(如
https://example.com/login)
示例代码:
```php$url = 'http://localhost/api/check.php';
$data = ['username' => 'test', 'token' => 'abc123'];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_REFERER, 'https://trusted-site.com/form'); // 关键:伪造来源
// 可选:跳过 SSL 验证(仅限开发环境)
// curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
```
file_get_contents + stream_context_create(轻量替代)
适合简单表单提交,不依赖 cURL 扩展。Referer 通过 stream_context_create() 的 header 项注入,但要注意:Content-Length 必须显式计算并写入 header,否则部分服务端会拒绝请求。
- 数据必须先用
http_build_query()转为 URL 编码字符串,不能直接传数组 - Header 中换行符用
\r\n,结尾需空行分隔 header 和 body - 不支持文件上传、复杂 Cookie 管理或细粒度超时控制
示例代码:
```php$url = 'http://localhost/api/check.php';
$data = http_build_query(['action' => 'submit', 'id' => 99]);
$refer = 'https://trusted-site.com/submit';
$opts = [
'http' => [
'method' => 'POST',
'header' => "Referer: $refer\r\n" .
"Content-type: application/x-www-form-urlencoded\r\n" .
"Content-length: " . strlen($data) . "\r\n",
'content' => $data,
],
];
$context = stream_context_create($opts);
$result = file_get_contents($url, false, $context);
echo $result;
```
fsockopen 手动构造 HTTP 请求(底层可控)
完全自主拼接原始 HTTP 报文,灵活性最高,也最易出错。Referer 作为标准请求头字段写入,需严格遵循 HTTP/1.1 格式(冒号后带空格、每行 \r\n 结尾、header 与 body 间空行)。
- 必须调用
parse_url()解析目标地址,提取 host、port、path - Port 未指定时默认为 80(HTTPS 则为 443,但
fsockopen不原生支持 TLS,需改用fsockopen('ssl://...')并额外处理证书) - Content-Length 值必须精确等于 POST 数据长度,否则连接可能被重置
示例关键片段:
```php$url = 'http://localhost/api/check.php';
$post_data = http_build_query(['cmd' => 'login']);
$url_info = parse_url($url);
$host = $url_info['host'];
$port = $url_info['port'] ?? 80;
$path = $url_info['path'] ?: '/';
$header = "POST $path HTTP/1.1\r\n";
$header .= "Host: $host\r\n";
$header .= "Referer: https://trusted-site.com/\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($post_data) . "\r\n";
$header .= "Connection: close\r\n\r\n";
$header .= $post_data;
$fp = fsockopen($host, $port);
fputs($fp, $header);
// 后续读取响应略
```
注意事项与常见陷阱
无论用哪种方式,以下几点直接影响 Referer 是否生效:
- 目标服务器是否真的检查
$_SERVER['HTTP_REFERER']—— 有些接口仅作日志记录,不校验;有些则严格匹配白名单 - 伪造的 Referer 地址协议(
httpvshttps)必须与目标预期一致,否则可能被中间网关过滤 - Apache 环境下伪造有效,Nginx 默认不传递伪造的 Referer,需确认其配置中未禁用该头(如
underscores_in_headers off;或安全模块拦截) - 若接口同时校验 Origin 和 Referer,仅伪造后者可能仍失败;Origin 无法通过 PHP 客户端伪造(浏览器专属)
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











