PHP 怎么PHP 代理

wen PHP项目 2

本文目录导读:

PHP 怎么PHP 代理

  1. 简单HTTP代理
  2. 完整的代理类
  3. 支持Cookie的代理
  4. 反向代理
  5. 安全注意事项
  6. 常用配置

我来详细解释PHP中如何实现代理功能。

简单HTTP代理

基本代理脚本

<?php
// simple_proxy.php
$target_url = $_GET['url'] ?? '';
if (empty($target_url)) {
    die('请提供目标URL');
}
// 初始化cURL
$ch = curl_init();
// 设置cURL选项
curl_setopt_array($ch, [
    CURLOPT_URL => $target_url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_SSL_VERIFYPEER => false,
    CURLOPT_SSL_VERIFYHOST => false,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_CONNECTTIMEOUT => 10,
]);
// 转发请求头(可选)
$headers = [];
foreach(getallheaders() as $name => $value) {
    if (!in_array(strtolower($name), ['host', 'connection', 'accept-encoding'])) {
        $headers[] = "$name: $value";
    }
}
if (!empty($headers)) {
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
// 转发POST数据
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($_POST));
}
// 执行请求
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
// 设置响应头
http_response_code($http_code);
if ($content_type) {
    header('Content-Type: ' . $content_type);
}
// 输出响应内容
echo $response;
curl_close($ch);
?>

使用示例

<!-- 在网页中使用 -->
<img src="simple_proxy.php?url=https://example.com/image.jpg">

完整的代理类

<?php
class Proxy {
    private $ch;
    private $options = [];
    private $headers = [];
    public function __construct() {
        $this->ch = curl_init();
        $this->setDefaultOptions();
    }
    private function setDefaultOptions() {
        $this->options = [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_CONNECTTIMEOUT => 10,
            CURLOPT_HEADER => true, // 获取响应头
        ];
    }
    public function setOption($option, $value) {
        $this->options[$option] = $value;
        return $this;
    }
    public function setHeader($header, $value) {
        $this->headers[$header] = $value;
        return $this;
    }
    public function forward($url, $method = 'GET', $data = null) {
        $this->options[CURLOPT_URL] = $url;
        $this->options[CURLOPT_CUSTOMREQUEST] = $method;
        // 设置请求头
        if (!empty($this->headers)) {
            $headers = [];
            foreach ($this->headers as $key => $value) {
                $headers[] = "$key: $value";
            }
            $this->options[CURLOPT_HTTPHEADER] = $headers;
        }
        // 处理POST数据
        if ($data !== null) {
            $this->options[CURLOPT_POSTFIELDS] = is_array($data) ? http_build_query($data) : $data;
        }
        // 设置所有选项
        curl_setopt_array($this->ch, $this->options);
        // 执行请求
        $response = curl_exec($this->ch);
        $info = curl_getinfo($this->ch);
        // 分离头部和内容
        $header_size = $info['header_size'];
        $response_headers = substr($response, 0, $header_size);
        $response_body = substr($response, $header_size);
        return [
            'headers' => $this->parseHeaders($response_headers),
            'body' => $response_body,
            'info' => $info,
        ];
    }
    private function parseHeaders($raw_headers) {
        $headers = [];
        foreach (explode("\r\n", $raw_headers) as $line) {
            if (strpos($line, ': ') !== false) {
                list($key, $value) = explode(': ', $line, 2);
                $headers[trim($key)] = trim($value);
            }
        }
        return $headers;
    }
    public function __destruct() {
        curl_close($this->ch);
    }
}
// 使用示例
$proxy = new Proxy();
$proxy->setHeader('User-Agent', 'Mozilla/5.0');
$result = $proxy->forward('https://api.example.com/data', 'POST', [
    'param1' => 'value1',
    'param2' => 'value2'
]);
print_r($result);
?>

支持Cookie的代理

<?php
class CookieAwareProxy {
    private $ch;
    private $cookie_file;
    public function __construct($cookie_file = null) {
        $this->ch = curl_init();
        $this->cookie_file = $cookie_file ?? tempnam(sys_get_temp_dir(), 'cookie');
        curl_setopt_array($this->ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_COOKIEFILE => $this->cookie_file,
            CURLOPT_COOKIEJAR => $this->cookie_file,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_USERAGENT => 'Mozilla/5.0',
        ]);
    }
    public function request($url, $method = 'GET', $data = null) {
        curl_setopt($this->ch, CURLOPT_URL, $url);
        curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, $method);
        if ($data) {
            curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data);
        }
        return curl_exec($this->ch);
    }
    public function __destruct() {
        curl_close($this->ch);
        if (file_exists($this->cookie_file)) {
            unlink($this->cookie_file);
        }
    }
}
// 使用示例
$proxy = new CookieAwareProxy();
$response = $proxy->request('https://example.com/login', 'POST', [
    'username' => 'admin',
    'password' => 'password'
]);
echo $response;
?>

反向代理

<?php
// reverse_proxy.php
$backend_host = 'http://backend-server:8080';
$request_uri = $_SERVER['REQUEST_URI'];
$target_url = $backend_host . $request_uri;
// 创建代理请求
$ch = curl_init($target_url);
// 设置选项
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HEADER => true,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_SSL_VERIFYPEER => false,
]);
// 转发请求方法
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $_SERVER['REQUEST_METHOD']);
// 转发请求体
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    curl_setopt($ch, CURLOPT_POSTFIELDS, file_get_contents('php://input'));
}
// 执行请求
$response = curl_exec($ch);
$info = curl_getinfo($ch);
// 分离响应头
$header_size = $info['header_size'];
$response_headers = substr($response, 0, $header_size);
$response_body = substr($response, $header_size);
// 设置响应头
foreach (explode("\r\n", $response_headers) as $header) {
    if (!empty($header) && !str_starts_with(strtolower($header), 'transfer-encoding')) {
        header($header);
    }
}
// 输出响应
echo $response_body;
curl_close($ch);
?>

安全注意事项

<?php
class SecureProxy {
    // 白名单域名
    private $allowed_domains = [
        'api.example.com',
        'cdn.example.com',
    ];
    // 黑名单IP
    private $blocked_ips = [
        '10.0.0.0/8',
        '172.16.0.0/12',
        '192.168.0.0/16',
    ];
    public function isAllowed($url) {
        $parsed_url = parse_url($url);
        $host = $parsed_url['host'] ?? '';
        // 检查白名单
        if (!in_array($host, $this->allowed_domains)) {
            return false;
        }
        // 检查IP黑名单
        $ip = gethostbyname($host);
        foreach ($this->blocked_ips as $blocked) {
            if ($this->ipInCIDR($ip, $blocked)) {
                return false;
            }
        }
        return true;
    }
    private function ipInCIDR($ip, $cidr) {
        list($range, $mask) = explode('/', $cidr);
        $range_int = ip2long($range);
        $ip_int = ip2long($ip);
        $mask_int = -1 << (32 - $mask);
        return ($ip_int & $mask_int) == ($range_int & $mask_int);
    }
    // URL验证
    public function validateUrl($url) {
        // 防止SSRF攻击
        if (!filter_var($url, FILTER_VALIDATE_URL)) {
            return false;
        }
        // 限制协议
        $scheme = parse_url($url, PHP_URL_SCHEME);
        if (!in_array($scheme, ['http', 'https'])) {
            return false;
        }
        // 限制端口
        $port = parse_url($url, PHP_URL_PORT);
        if ($port && !in_array($port, [80, 443, 8080])) {
            return false;
        }
        return true;
    }
}
?>

常用配置

<?php
// 代理配置示例
$proxy_config = [
    // 超时设置
    'timeout' => 30,
    'connect_timeout' => 10,
    // 代理服务器(如果需要)
    'proxy' => [
        'host' => 'proxy.example.com',
        'port' => 8080,
        'auth' => 'username:password', // 可选
    ],
    // 缓存设置
    'cache' => [
        'enabled' => true,
        'ttl' => 3600, // 1小时
    ],
    // 速率限制
    'rate_limit' => [
        'requests' => 100,
        'period' => 60, // 每分钟
    ],
];
?>

PHP实现代理的主要方式:

  1. 简单代理:使用curl直接转发请求
  2. 完整代理类:封装更多功能
  3. Cookie支持:保持会话状态
  4. 反向代理:隐藏后端服务器
  5. 安全控制:防止滥用和攻击

根据实际需求选择合适的实现方式。

抱歉,评论功能暂时关闭!