当前位置:首页 > PHP

php实现http代理

2026-02-27 19:34:27PHP

实现HTTP代理的基本原理

HTTP代理服务器充当客户端和目标服务器之间的中间人,接收客户端请求并转发给目标服务器,再将响应返回给客户端。PHP可通过Socket或cURL扩展实现这一功能。

使用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);

$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);
?>

使用Socket实现更完整的代理

<?php
$proxyPort = 8080;
$proxyHost = '0.0.0.0';

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, $proxyHost, $proxyPort);
socket_listen($socket);

while (true) {
    $client = socket_accept($socket);
    $request = socket_read($client, 1024);

    preg_match('/Host: (.+)/', $request, $matches);
    $host = trim($matches[1]);

    $targetSocket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    socket_connect($targetSocket, $host, 80);
    socket_write($targetSocket, $request);

    $response = '';
    while ($buffer = socket_read($targetSocket, 1024)) {
        $response .= $buffer;
    }

    socket_write($client, $response);
    socket_close($targetSocket);
    socket_close($client);
}
?>

处理HTTPS请求的注意事项

对于HTTPS请求,需要处理CONNECT方法并建立隧道:

if (strpos($request, 'CONNECT') === 0) {
    $parts = explode(' ', $request);
    $target = trim($parts[1]);
    list($host, $port) = explode(':', $target);

    $targetSocket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    socket_connect($targetSocket, $host, $port);

    socket_write($client, "HTTP/1.1 200 Connection Established\r\n\r\n");

    // 双向转发数据
    while (true) {
        $data = socket_read($client, 4096);
        if (!$data) break;
        socket_write($targetSocket, $data);

        $data = socket_read($targetSocket, 4096);
        if (!$data) break;
        socket_write($client, $data);
    }
}

性能优化建议

使用stream_socket_server替代原生socket函数可获得更好性能:

$server = stream_socket_server("tcp://$proxyHost:$proxyPort");
while ($client = stream_socket_accept($server)) {
    $request = fread($client, 8192);
    // 处理请求逻辑
}

实现连接池管理重复使用的目标服务器连接,减少频繁建立连接的开销。考虑加入缓存机制对频繁请求的响应进行缓存。

安全注意事项

验证目标URL防止开放代理被滥用:

$allowedDomains = ['example.com', 'api.example.org'];
$parsed = parse_url($targetUrl);
if (!in_array($parsed['host'], $allowedDomains)) {
    http_response_code(403);
    die('Access to this domain is not allowed');
}

实现身份验证机制:

if (!isset($_SERVER['PHP_AUTH_USER']) || 
    $_SERVER['PHP_AUTH_USER'] != 'proxyuser' || 
    $_SERVER['PHP_AUTH_PW'] != 'proxypass') {
    header('WWW-Authenticate: Basic realm="Proxy Auth"');
    http_response_code(401);
    die('Authentication required');
}

记录日志监控代理使用情况:

$log = sprintf("[%s] %s %s\n", 
    date('Y-m-d H:i:s'), 
    $_SERVER['REMOTE_ADDR'],
    $targetUrl);
file_put_contents('proxy.log', $log, FILE_APPEND);

php实现http代理

标签: phphttp
分享给朋友:

相关文章

php实现socket

php实现socket

PHP 实现 Socket 通信 PHP 可以通过 socket 扩展实现网络通信,支持 TCP/UDP 协议。以下是实现 Socket 通信的核心步骤和代码示例。 创建 TCP 服务器 //…

php实现增删改查

php实现增删改查

以下是在PHP中实现增删改查(CRUD)操作的详细方法,以MySQL数据库为例: 数据库连接配置 创建config.php文件存储数据库连接信息: <?php $host = 'localh…

php实现mysql

php实现mysql

PHP 连接 MySQL 的基本方法 PHP 提供了多种方式与 MySQL 数据库进行交互,以下是最常用的几种方法。 使用 MySQLi 扩展 MySQLi 是 MySQL 的改进扩展,支持面向对…

php 实现文件下载

php 实现文件下载

实现文件下载的基本方法 使用 PHP 实现文件下载的核心是通过设置 HTTP 头部信息,强制浏览器将文件作为附件下载而非直接显示。以下是一个基础实现示例: $file_path = '/path/…

php实现聊天

php实现聊天

实现 PHP 聊天功能的方法 使用 WebSocket 和 PHP 实现实时聊天 WebSocket 是一种全双工通信协议,适合实现实时聊天功能。PHP 可以通过 Ratchet 库实现 WebSo…

php实现即时通讯

php实现即时通讯

PHP 实现即时通讯的方案 即时通讯(IM)可以通过多种方式实现,PHP 作为服务器端语言,通常需要结合前端技术(如 WebSocket、AJAX)或第三方服务来实现实时通信。以下是几种常见的实现方式…