本文目录导读:

在 PHP 中实现反向代理,通常有两种场景:
- 作为应用层代理:PHP 脚本接收请求后,通过
cURL或file_get_contents向目标服务器发起新的请求,再返回结果。 - 利用 Web 服务器功能:通过 Nginx 或 Apache 配置反向代理,PHP 本身不参与代理逻辑(性能最佳)。
下面分别说明两种实现方式,重点聚焦 PHP 代码实现反向代理。
纯 PHP 实现反向代理(适合小流量或特殊业务)
PHP 作为代理服务器,接收所有请求后转发给后端目标服务器。
基础示例(仅代理 GET 请求)
<?php
$targetUrl = 'http://192.168.1.100:8080'; // 目标服务器地址
// 获取当前请求的路径和查询参数
$path = $_SERVER['REQUEST_URI'];
$finalUrl = $targetUrl . $path;
// 初始化 cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $finalUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
// 转发请求头(可选)
$headers = getallheaders();
$curlHeaders = [];
foreach ($headers as $key => $value) {
$curlHeaders[] = "$key: $value";
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $curlHeaders);
// 执行请求
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// 设置响应状态码
http_response_code($httpCode);
// 设置 Content-Type(若有)
// 这里简单范例不做解析,实际可以获取目标响应的 header
// 输出结果
echo $response;
完整的代理函数(支持 GET/POST/PUT/DELETE、请求体、自定义头)
<?php
function reverseProxy($targetBaseUrl) {
$url = $targetBaseUrl . $_SERVER['REQUEST_URI'];
$method = $_SERVER['REQUEST_METHOD'];
// 获取请求体
$body = file_get_contents('php://input');
// 获取客户端请求头
$headers = getallheaders();
$curlHeaders = [];
foreach ($headers as $key => $value) {
// 可过滤掉一些不宜转发的头(如 Host, Connection)
if (strtolower($key) !== 'host' && strtolower($key) !== 'connection') {
$curlHeaders[] = "$key: $value";
}
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_HTTPHEADER, $curlHeaders);
// 有请求体时发送
if ($body) {
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
}
// 获取响应头(如果需要转发响应头给客户端)
curl_setopt($ch, CURLOPT_HEADER, true);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// 分离响应头和响应体
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$responseHeader = substr($response, 0, $headerSize);
$responseBody = substr($response, $headerSize);
curl_close($ch);
// 设置 HTTP 状态码
http_response_code($httpCode);
// 转发响应头(可选)
$headerLines = explode("\r\n", $responseHeader);
foreach ($headerLines as $line) {
if (stripos($line, 'Transfer-Encoding') === false &&
stripos($line, 'Connection') === false) {
header($line, false);
}
}
echo $responseBody;
}
// 使用
reverseProxy('http://backend-server:8080');
注意事项:
- 纯 PHP 代理性能较差,每次请求都会消耗 PHP 进程来处理转发,不适合高并发。
- 需要处理 cookie、SSL、超时、连接池等问题。
- 建议配合 Web 服务器(如 Nginx 转发到 PHP-FPM)使用,而非直接监听外部端口。
使用 Web 服务器反向代理(推荐生产环境)
Nginx 配置示例
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:8080; # 后端服务地址
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Apache 配置示例(需启用 mod_proxy)
<VirtualHost *:80>
ServerName example.com
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
</VirtualHost>
PHP 在这种情况下无需任何代理代码,只负责处理业务逻辑。
使用 PHP 第三方库实现代理
如果非要纯 PHP 且想减少代码量,可使用 guzzlehttp/guzzle 配合中间件:
但最终原理仍是 cURL,只是封装了更多功能。
composer require guzzlehttp/guzzle
<?php use GuzzleHttp\Client; use GuzzleHttp\Psr7\Request; require 'vendor/autoload.php'; $client = new Client(['base_uri' => 'http://target-server/']); $request = new Request($_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI']); $response = $client->send($request); // 转发状态码和响应 http_response_code($response->getStatusCode()); echo $response->getBody();
| 方式 | 适用场景 | 性能 | 复杂度 |
|---|---|---|---|
| Web服务器反向代理 (Nginx/Apache) | 生产环境、高并发 | 极高 | 低(只需配置) |
| PHP cURL 代码代理 | 小流量、特殊业务(如需修改请求/响应) | 低 | 中 |
| PHP 框架/库代理 | 快速开发,已有 Guzzle 环境 | 低 | 中 |
建议:
- 大部分情况下使用 Nginx 反向代理。
- 只有当需要动态修改请求或响应内容、或无法修改 Web 服务器配置时,才考虑 PHP 代码实现代理。
如果需要在 PHP 中实现更完整的代理(支持 WebSocket、长连接、负载均衡等),请进一步说明你的具体需求,可以提供更定制化的方案。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播