php实现代理服务器
实现 PHP 代理服务器的基本方法
PHP 可以通过流上下文(Stream Context)或 cURL 扩展实现代理服务器功能。以下是两种常见实现方式:
使用 stream_context_create 实现
通过 PHP 内置的流功能创建代理请求:
<?php
$targetUrl = $_GET['url'] ?? '';
if (empty($targetUrl)) {
die('Missing URL parameter');
}
$context = stream_context_create([
'http' => [
'method' => $_SERVER['REQUEST_METHOD'],
'header' => getallheaders(),
'ignore_errors' => true
]
]);
$response = file_get_contents($targetUrl, false, $context);
header('Content-Type: ' . $http_response_header[0]);
echo $response;
?>
使用 cURL 扩展实现
更强大的代理实现方式,支持更多协议和选项:
<?php
$targetUrl = $_GET['url'] ?? '';
if (empty($targetUrl)) {
die('Missing URL parameter');
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $targetUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HEADER, true);
// 传递原始请求头
$headers = [];
foreach (getallheaders() as $name => $value) {
$headers[] = "$name: $value";
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($response, 0, $headerSize);
$body = substr($response, $headerSize);
// 转发响应头
foreach (explode("\r\n", $headers) as $header) {
if (!empty($header)) {
header($header);
}
}
echo $body;
curl_close($ch);
?>
安全性注意事项
实现代理服务器时需要考虑以下安全措施:
验证目标URL,防止SSRF攻击:
$allowedDomains = ['example.com', 'trusted-site.com'];
$parsedUrl = parse_url($targetUrl);
if (!in_array($parsedUrl['host'], $allowedDomains)) {
die('Access to this domain is not allowed');
}
限制请求大小防止滥用:
$maxSize = 1024 * 1024; // 1MB
if (strlen($response) > $maxSize) {
die('Response too large');
}
性能优化建议
对于高频使用的代理服务器,可以考虑以下优化:
启用缓存减少重复请求:
$cacheKey = md5($targetUrl);
$cacheFile = "/tmp/proxy_cache_$cacheKey";
if (file_exists($cacheFile) && (time() - filemtime($cacheFile) < 3600)) {
readfile($cacheFile);
exit;
}
// ...处理请求...
file_put_contents($cacheFile, $response);
使用连接池保持持久连接:
curl_setopt($ch, CURLOPT_FORBID_REUSE, false);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, false);
完整代理服务器示例
结合上述技术的完整实现:
<?php
// 安全配置
$allowedDomains = ['example.com', 'trusted-site.com'];
$maxSize = 1024 * 1024; // 1MB
// 获取目标URL
$targetUrl = $_GET['url'] ?? '';
if (empty($targetUrl)) {
http_response_code(400);
die('Missing URL parameter');
}
// 验证目标域名
$parsedUrl = parse_url($targetUrl);
if (!isset($parsedUrl['host']) || !in_array($parsedUrl['host'], $allowedDomains)) {
http_response_code(403);
die('Access to this domain is not allowed');
}
// 初始化cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $targetUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HEADER, true);
// 传递请求头
$headers = [];
foreach (getallheaders() as $name => $value) {
if (strtolower($name) !== 'host') { // 排除Host头
$headers[] = "$name: $value";
}
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// 执行请求
$response = curl_exec($ch);
if (strlen($response) > $maxSize) {
http_response_code(413);
die('Response too large');
}
// 处理响应
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($response, 0, $headerSize);
$body = substr($response, $headerSize);
// 转发响应头
foreach (explode("\r\n", $headers) as $header) {
if (!empty($header)) {
header($header);
}
}
echo $body;
curl_close($ch);
?>
以上代码提供了PHP实现代理服务器的基本框架,可根据实际需求进行调整和扩展。







