PHP 发起代理请求最可靠的路径是 cURL 扩展:CURLOPT_PROXY 一个选项即可把请求交给代理服务器,配合 CURLOPT_PROXYUSERPWD、CURLOPT_TIMEOUT 等选项可以覆盖认证、超时与跳转等全部细节。无论是采集公开数据、聚合第三方接口,还是调用需要固定出口 IP 的服务,这套组合都足够稳定。本文从扩展检查讲到完整示例,再逐条拆解高频错误码的排查方法。
环境准备与扩展确认
命令行执行 php -m 查看已加载模块,输出列表里应当包含 curl;也可以新建 phpinfo() 页面,确认 cURL support 一栏为 enabled。缺失时在 php.ini 中去掉 extension=curl 前的分号并重启服务,Linux 下还需确认系统层的 php-curl 软件包已安装。CLI 与 FPM 使用的 php.ini 可能不是同一份,修改后要分别确认生效。
- CLI 检查:php -m 或 php --ri curl 查看扩展版本与特性。
- 开启扩展:php.ini 中启用 extension=curl 后重启 PHP-FPM 或 Web 服务。
- 系统包:Ubuntu 执行 apt install php-curl,CentOS 使用 yum install php-curl。
cURL 常用代理选项一览
CURLOPT_PROXY 支持直接写完整地址,也支持 host:port 简写;认证交给 CURLOPT_PROXYUSERPWD,值为「用户名:密码」字符串。CURLOPT_RETURNTRANSFER 把响应体作为字符串返回而不是直接输出到标准输出;CURLOPT_FOLLOWLOCATION 处理 301、302 跳转;CURLOPT_CONNECTTIMEOUT 与 CURLOPT_TIMEOUT 分别限制与代理建连和请求总时长。所有选项可以一次性传入 curl_setopt_array,比逐行调用更整洁也更易维护。
完整代码示例
下面的例子完成一次经代理的 GET 请求,包含错误处理与状态码读取:
<?php
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => 'https://httpbin.org/ip',
CURLOPT_PROXY => 'http://127.0.0.1:8080',
CURLOPT_PROXYUSERPWD => 'user:pass',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_USERAGENT => 'Mozilla/5.0',
CURLOPT_SSL_VERIFYPEER => true,
]);
$response = curl_exec($ch);
if ($response === false) {
echo '请求失败: ' . curl_error($ch)
. ' (错误码 ' . curl_errno($ch) . ')' . PHP_EOL;
} else {
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
echo "状态码: $code" . PHP_EOL;
echo $response . PHP_EOL;
}
curl_close($ch);
curl_exec 失败时返回 false,此时 curl_errno 与 curl_error 分别给出错误码和可读信息,务必成对记录到日志。curl_getinfo 除状态码外还能拿到 total_time、primary_ip 等指标,非常适合做代理质量的监控统计。
HTTPS 与 SOCKS5 代理的支持
目标 URL 是 https:// 时,cURL 会自动向 HTTP 代理发送 CONNECT 请求建立隧道,保持 CURLOPT_SSL_VERIFYPEER 为 true 即可安全通信。SOCKS5 代理把 CURLOPT_PROXY 设为 socks5://host:port,或额外设置 CURLOPT_PROXYTYPE 为 CURLPROXY_SOCKS5;希望域名解析也发生在代理端时使用 socks5h:// 前缀,可规避本地 DNS 污染。使用 Guzzle 等封装层时,这些底层选项对应 proxy 配置数组里的 uri 与 scheme 字段,原理完全相通。
常见错误码与注意事项
- 错误码 7:无法连接代理,检查地址、端口与防火墙放行情况。
- 错误码 28:操作超时,分别调大连接超时与总超时再观察。
- 错误码 35 或 60:TLS 握手或证书校验失败,应导入 CA 证书而非关闭校验。
- 状态码 407:代理认证失败,核对账号密码与出口 IP 白名单。
Article ID: 36
(本文仅供技术交流,请遵守法律法规)