Guzzle can use its native proxy option with console residential credentials. URL-encode the username and password. Fake placeholders; real code blocks. Not for mainland China.
Copy protocol, host, port, and auth from the console, then put them in Guzzle. Guzzle’s `proxy` request option usually accepts an HTTP proxy URL directly. That differs from Axios, which often needs an extra agent and `proxy: false`—see Node.js and Axios. Python: use a residential proxy in Python.
ZTProxy sells rotating residential (per GB) and static residential (per IP·month). Examples use fake placeholders—not production hosts. Authorized targets only. Not for mainland China.
What to have ready
| Ready item | Source |
|---|---|
| Protocol, host, port, auth | Console values only (not the fake placeholders) |
| PHP and `guzzlehttp/guzzle` | Your local environment |
| Check URL | An HTTPS target you may access |
| Rotating or static order | Rotating vs static |
Placeholders (not production): host `proxy.example.invalid`, port `10000`, user `USER_EXAMPLE`, password `PASS_EXAMPLE_NOT_REAL`. Strings: proxy format. Protocol: HTTP / SOCKS5 setup. Commands follow Docs EN quickstart. You can also confirm the same credentials with curl first.
Recommended pattern: Guzzle’s proxy option
Keep credentials in environment variables. URL-encode the username or password if it contains `@` or `:`. Do not invent country or session fields in the username.
<?php
require __DIR__ . "/vendor/autoload.php";
use GuzzleHttp\Client;
$user = rawurlencode(getenv("ZT_PROXY_USER") ?: "USER_EXAMPLE");
$pass = rawurlencode(getenv("ZT_PROXY_PASS") ?: "PASS_EXAMPLE_NOT_REAL");
$host = getenv("ZT_PROXY_HOST") ?: "proxy.example.invalid";
$port = getenv("ZT_PROXY_PORT") ?: "10000";
$client = new Client([
"proxy" => "http://{$user}:{$pass}@{$host}:{$port}",
"timeout" => 30,
]);
$res = $client->request("GET", "https://example.com");
echo $res->getStatusCode(), "\n";
Use SOCKS5 only when the console returns SOCKS and your handler can speak SOCKS. Do not assume UDP is available. Avoid stacking an extra environment proxy on top, or the request may bypass your settings or be proxied twice.
Sessions and common issues
Reusing one `Client` may reuse a gateway connection. That is not a static IP, and it is not automatically a sticky session. See sticky ≠ static.
| Symptom | Check first |
|---|---|
| 407 | Username/password, URL encoding, order still valid |
| Still your machine IP | `proxy` actually applied on that request; not overridden by the environment |
| Timeouts | Protocol and port match the console; you did not leave the fake host in place |
| Wrong region | The order region; do not invent username syntax |
Fuller symptom table: 407 and timeouts.
Compliance and scope
Authorized targets only. This is not a bypass tutorial. Prices follow the console and pricing (rotating about $0.40/GB, about $0.20/GB on a 100 TB full bundle; static about $1.50 shared and about $5 dedicated per IP/month). USDT/USDC available; Visa/Mastercard in application. Not for mainland China.
FAQ
Why can Guzzle use proxy directly when Axios often cannot?
Clients differ. Axios often needs an extra agent for HTTPS tunneling; Guzzle’s `proxy` option usually works as-is. Both still take credentials from the console.
Can I use the example host as-is?
No. Replace it with console values.
Can I append -country-us to the username myself?
Do not invent syntax. Use only fields the console or docs define.
If I reuse the Client, do I keep the same IP?
Not necessarily. Connection reuse is not static, and it is not automatically sticky.
Do I need an extra PHP proxy extension?
This example uses Guzzle’s official `proxy` option only. No fictional product extension is required.
Can I use this to bypass login limits?
No. Authorized targets only.
Should I pick PHP, Python, or Node?
Use the runtime you already run. The credential source is the same: the console.
Where are prices confirmed?
In the console and on pricing.