v1.10.82-f67ee7d
Skip to main content
← Back to Code Snippets

PHP cURL Proxy

Complete cURL proxy integration example for PHP with Hex Proxies. Includes authentication, timeouts, and error handling.

PHPcURL
Install:PHP cURL extension (built-in). No additional install required.
PHP / cURL
<?php
$ch = curl_init();

curl_setopt_array($ch, [
    CURLOPT_URL            => "https://httpbin.org/ip",
    CURLOPT_PROXY          => "gate.hexproxies.com:8080",
    CURLOPT_PROXYUSERPWD   => "user:pass",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT        => 30,
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_SSL_VERIFYPEER => true,
]);

$response = curl_exec($ch);

if (curl_errno($ch)) {
    echo "cURL error: " . curl_error($ch) . "\n";
} else {
    $data = json_decode($response, true);
    echo "Origin IP: " . $data["origin"] . "\n";
}

curl_close($ch);
?>

Why PHP cURL for Proxy Work

PHP powers over 75 percent of websites with a known server-side language, and cURL is its most battle-tested HTTP extension. The PHP cURL bindings provide direct access to libcurl, the same C library that powers the curl command-line tool, giving PHP developers access to every proxy protocol, authentication method, and connection tuning parameter that libcurl supports. This is not a high-level wrapper with a subset of features; it is the full power of the most widely deployed HTTP transfer library in the world, available through PHP's procedural or object-oriented interfaces.

PHP's request lifecycle model, where each web request spawns a fresh PHP process (or reuses one via PHP-FPM), aligns naturally with proxy workflows that need request-level isolation. Each PHP process can configure its own proxy connection to gate.hexproxies.com:8080 without worrying about shared state, connection pool corruption, or thread safety. This process-isolation model eliminates entire categories of concurrency bugs that plague long-running proxy applications in other languages.

Configuration Patterns

PHP cURL uses `curl_setopt()` or `curl_setopt_array()` to configure proxy behavior through libcurl constants. `CURLOPT_PROXY` sets the proxy gateway address, `CURLOPT_PROXYUSERPWD` provides credentials in `user:pass` format, and `CURLOPT_PROXYTYPE` specifies the protocol (HTTP, HTTPS, SOCKS4, SOCKS5). For HTTPS proxies, set `CURLOPT_PROXY` with an `https://` prefix and optionally configure `CURLOPT_PROXY_SSL_VERIFYPEER` to validate the proxy's TLS certificate.

PHP cURL's multi-handle interface (`curl_multi_init()`) enables concurrent proxied requests within a single PHP process. Add multiple cURL handles to the multi-handle, each configured with its own proxy settings, and execute them simultaneously with `curl_multi_exec()`. This is PHP's mechanism for parallel HTTP requests and is essential for workloads that need to fan out to multiple targets through the proxy within a single request lifecycle.

Common Pitfalls

The most frequent PHP proxy error is disabling `CURLOPT_SSL_VERIFYPEER` to "fix" certificate verification failures. This bypasses TLS validation entirely, exposing your traffic to man-in-the-middle attacks. Instead, ensure your PHP installation has an up-to-date CA certificate bundle by setting `curl.cainfo` in php.ini or passing `CURLOPT_CAINFO` with the path to a current certificate bundle (downloadable from curl.se/ca/cacert.pem).

PHP's default `max_execution_time` of 30 seconds can conflict with proxy timeouts. If your cURL request takes 25 seconds due to proxy latency and your script does additional processing, PHP may terminate the script before it finishes. Set `max_execution_time` in your php.ini or use `set_time_limit()` at runtime to accommodate proxy-related delays. Also watch for `memory_limit` issues when downloading large responses through the proxy; stream large responses to disk using `CURLOPT_FILE` instead of buffering them in memory with `CURLOPT_RETURNTRANSFER`.

Performance Optimization

For PHP applications that make many proxied requests, persistent cURL handles dramatically reduce overhead. Instead of calling `curl_init()` and `curl_close()` for each request, reuse the handle by calling `curl_reset()` between requests. This maintains the underlying TCP connection to the proxy across requests, eliminating the 50-100ms connection setup cost. In PHP-FPM environments, store the cURL handle in a static variable to persist it across requests within the same worker process.

PHP 8.1+ introduced fiber support, which provides cooperative concurrency similar to async/await in other languages. Libraries like AMPHP and ReactPHP leverage fibers to manage hundreds of concurrent proxied requests from a single PHP process. While cURL multi-handles provide basic parallelism, fiber-based HTTP clients offer cleaner APIs and better error handling for complex proxy workflows that involve conditional logic between requests.

Tips

  • 1
    Always set CURLOPT_RETURNTRANSFER to capture the response body.
  • 2
    Keep CURLOPT_SSL_VERIFYPEER enabled in production for security.
  • 3
    Use CURLOPT_CONNECTTIMEOUT separately from CURLOPT_TIMEOUT for proxy-specific latency.

Ready to Integrate?

Get proxy credentials and start coding in minutes.