NP NEONPROXYPROXY NETWORK
КупитьЦеныFAQПартнёркаБлог Прокси-чекерМой IPAPI TG-бот

Прокси в PHP cURL: настройка и отладка

PHP остаётся рабочей лошадкой для CRM-интеграций, парсеров каталогов и cron-задач на shared-хостинге. Расширение cURL поддерживает HTTP- и SOCKS-прокси нативно — достаточно нескольких констант. В этом гайде разберём настройку под данные NEONPROXY, отладку через curl_getinfo и типичные ошибки, с которыми сталкиваются при переходе с локальной разработки на production.

Базовая конфигурация HTTPS-прокси

После заказа вы получаете строку host:port:login:password. Для cURL прокси указывается отдельно от URL авторизации:

$host = "185.22.34.89"; $port = 8080; $user = "user_a1b2"; $pass = "pass_x9y8"; $ch = curl_init("https://api.ipify.org?format=json"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 15, CURLOPT_PROXY => "$host:$port", CURLOPT_PROXYUSERPWD => "$user:$pass", CURLOPT_PROXYTYPE => CURLPROXY_HTTP, CURLOPT_HTTPPROXYTUNNEL => true, ]); $body = curl_exec($ch); $info = curl_getinfo($ch); curl_close($ch); echo $body; // {"ip":"185.22.34.89"}

Опция CURLOPT_HTTPPROXYTUNNEL обязательна для HTTPS через HTTP-прокси: без неё cURL попытается отправить абсолютный URL вместо CONNECT-туннеля.

SVYAZVPN — свобода без границ

SOCKS5 в PHP

Для SOCKS5 замените тип прокси и порт на выданный в кабинете (обычно 1080):

curl_setopt_array($ch, [ CURLOPT_PROXY => "$host:1080", CURLOPT_PROXYUSERPWD => "$user:$pass", CURLOPT_PROXYTYPE => CURLPROXY_SOCKS5_HOSTNAME, ]);

Константа CURLPROXY_SOCKS5_HOSTNAME резолвит DNS через прокси — это важно, когда целевой домен блокируется на уровне провайдера сервера. Сравнение протоколов — в статье SOCKS5 vs HTTPS.

Обёртка с ротацией пула

Для задач мониторинга публичных цен и статусов страниц распределяйте нагрузку по нескольким IP:

class ProxyPool { private array $proxies; private int $idx = 0; public function __construct(array $lines) { $this->proxies = array_map(function ($line) { [$h, $p, $u, $pw] = explode(":", $line); return compact("h", "p", "u", "pw"); }, $lines); } public function next(): array { return $this->proxies[$this->idx++ % count($this->proxies)]; } } function fetchViaProxy(string $url, array $px): string { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 20, CURLOPT_PROXY => "{$px["h"]}:{$px["p"]}", CURLOPT_PROXYUSERPWD => "{$px["u"]}:{$px["pw"]}", CURLOPT_HTTPPROXYTUNNEL => true, ]); $body = curl_exec($ch); if (curl_errno($ch)) throw new RuntimeException(curl_error($ch)); curl_close($ch); return $body; }

Актуальный список адресов можно получать через API NEONPROXY — см. также материал про интеграцию API.

Отладка: curl_getinfo и verbose

После curl_exec проверяйте массив curl_getinfo($ch): поля http_code, total_time и primary_ip покажут, через какой адрес прошёл запрос. Для глубокой отладки включите verbose в поток:

$verbose = fopen("php://temp", "w+"); curl_setopt($ch, CURLOPT_VERBOSE, true); curl_setopt($ch, CURLOPT_STDERR, $verbose); // ... curl_exec ... rewind($verbose); echo stream_get_contents($verbose);

На production verbose отключайте — лог может содержать пароли. Перед деплоем прогоните прокси через чекер и проверку анонимности.

Типичные ошибки

407 Proxy Authentication Required — неверный login:password или лишние пробелы при парсинге строки из кабинета. Connection timed out — firewall на VPS блокирует исходящий порт прокси; проверьте через сканер портов. SSL certificate problem — чаще проблема целевого сайта; не отключайте CURLOPT_SSL_VERIFYPEER в production без веской причины.

Используйте прокси только для задач, разрешённых правилами целевого сервиса и применимым законодательством. Сбор персональных данных без согласия, обход CAPTCHA и авторизация под чужими учётными записями — вне scope легального применения инфраструктуры NEONPROXY.

Guzzle как альтернатива

Если проект уже на Guzzle, прокси задаётся в опциях клиента: 'proxy' => 'http://user:pass@host:port'. Guzzle использует cURL под капотом, поэтому правила те же. Для Laravel HTTP-клиента достаточно передать массив withOptions(['proxy' => ...]).