-
Check the cURL extension
Most PHP builds include the cURL extension; confirm it is loaded before you start. Install Guzzle with Composer only if you prefer a higher-level client.
Shell php -m | grep -i curl composer require guzzlehttp/guzzle # optional -
Send a request through the gateway
Set the gateway with
CURLOPT_PROXYand your credentials withCURLOPT_PROXYUSERPWD. HTTPS targets are tunneled through CONNECT automatically.PHP <?php $ch = curl_init('https://api.ipify.org'); curl_setopt_array($ch, [ CURLOPT_PROXY => 'http://gw.proxonym.com:8000', CURLOPT_PROXYUSERPWD => 'USERNAME:PASSWORD', CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 60, ]); $ip = curl_exec($ch); echo $ip === false ? 'Error: ' . curl_error($ch) : 'Exit IP: ' . $ip, PHP_EOL; -
Target a country, state, city or ASN
This helper appends parameters to the username in the order the gateway expects. Use lowercase ISO country codes and underscores for spaces, and pick a state or a city, not both.
PHP <?php function proxonym_user(array $params = []): string { $user = 'USERNAME'; foreach (['country', 'state', 'city', 'asn', 'session', 'lifetime'] as $key) { if (isset($params[$key])) { $user .= "-{$key}-{$params[$key]}"; } } return $user; } function fetch_via_proxy(string $url, string $user): string { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_PROXY => 'http://gw.proxonym.com:8000', CURLOPT_PROXYUSERPWD => $user . ':PASSWORD', CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 60, ]); $body = curl_exec($ch); return $body === false ? 'error: ' . curl_error($ch) : $body; } echo fetch_via_proxy('https://ipinfo.io/json', proxonym_user(['country' => 'gb', 'city' => 'london'])), PHP_EOL; echo fetch_via_proxy('https://ipinfo.io/json', proxonym_user(['country' => 'us', 'state' => 'texas'])), PHP_EOL; echo fetch_via_proxy('https://ipinfo.io/json', proxonym_user(['country' => 'us', 'asn' => 7922])), PHP_EOL; -
Rotate or keep the same IP
Each new cURL handle opens a new connection, and without a session parameter every new connection gets a new IP. With the helpers from the previous step, add a session ID of up to 32 letters and digits to keep one IP for up to 120 minutes.
PHP // Rotating: a new exit IP for every handle for ($i = 0; $i < 3; $i++) { echo 'rotating ', fetch_via_proxy('https://api.ipify.org', proxonym_user(['country' => 'us'])), PHP_EOL; } // Sticky: the same exit IP for up to 30 minutes $sticky = proxonym_user(['country' => 'us', 'session' => bin2hex(random_bytes(4)), 'lifetime' => 30]); for ($i = 0; $i < 3; $i++) { echo 'sticky ', fetch_via_proxy('https://api.ipify.org', $sticky), PHP_EOL; } -
Use Guzzle or SOCKS5
Guzzle takes the whole proxy URL, credentials included, in its
proxyoption. Switch the scheme tosocks5h://and the port to 1080 to use SOCKS5 with DNS resolved on the proxy side.PHP <?php require 'vendor/autoload.php'; use GuzzleHttp\Client; $http = new Client([ 'proxy' => 'http://USERNAME-country-de:[email protected]:8000', 'timeout' => 60, ]); echo 'HTTP: ', $http->get('https://api.ipify.org')->getBody(), PHP_EOL; $socks = new Client([ 'proxy' => 'socks5h://USERNAME-country-de:[email protected]:1080', 'timeout' => 60, ]); echo 'SOCKS5: ', $socks->get('https://api.ipify.org')->getBody(), PHP_EOL; -
Read gateway status codes and retry
For HTTPS targets,
CURLINFO_HTTP_CONNECTCODEholds the gateway status for the CONNECT request. Retry 429, 502 and 504 after a pause, and stop on 402, 403 or 407, which retries cannot fix.PHP <?php function fetch_with_retry(string $url, string $user, int $tries = 3): string { for ($attempt = 1; $attempt <= $tries; $attempt++) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_PROXY => 'http://gw.proxonym.com:8000', CURLOPT_PROXYUSERPWD => $user . ':PASSWORD', CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 60, ]); $body = curl_exec($ch); $gateway = curl_getinfo($ch, CURLINFO_HTTP_CONNECTCODE); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($body !== false && $status !== 429 && $status < 500) { return $body; } if (in_array($gateway, [402, 403, 407], true)) { throw new RuntimeException("Gateway refused the request with status $gateway"); } sleep($attempt); } throw new RuntimeException("Request failed after $tries attempts"); } echo strlen(fetch_with_retry('https://example.com', 'USERNAME-country-us')), ' bytes', PHP_EOL;
Frequently asked questions
How do I see the gateway status for HTTPS requests in PHP?
Call curl_getinfo($ch, CURLINFO_HTTP_CONNECTCODE) after curl_exec. For HTTPS targets it returns the status the gateway sent in reply to the CONNECT request, while CURLINFO_RESPONSE_CODE returns the status from the target site. A 407 means wrong credentials, 402 an empty balance or expired plan, and 403 a blocked target.
Does Guzzle work with Proxonym proxies?
Yes. Pass the full proxy URL in the proxy option, either on the client or on a single request to override it. You can also pass an array with separate http and https entries. Guzzle hands the URL to cURL, so socks5h:// URLs on port 1080 work too, with the same username parameters.
Why do several requests share the same IP?
They probably reuse one cURL handle, which keeps its connection to the gateway open, and the gateway assigns IPs per connection. Create a new handle for each request, or set CURLOPT_FRESH_CONNECT to true, when every request needs a new IP. Keep the handle when you want a stable IP and use a session ID.
Can I use the SOCKS5 endpoint from PHP?
Yes. Set CURLOPT_PROXY to socks5h://gw.proxonym.com:1080 and keep CURLOPT_PROXYUSERPWD as before. The socks5h scheme makes the proxy resolve hostnames, so DNS lookups stay off your server. Targeting, session and lifetime parameters in the username behave exactly as they do on the HTTP endpoint.
