Skip to content

Commit 79923cd

Browse files
committed
Add comprehensive PHP proxy examples
Adds examples for 6 PHP HTTP libraries: - cURL (native) - Guzzle - Symfony HttpClient - Buzz - PHP Streams - Amp HTTP Includes composer.json, test runner, and updated README with documentation. Made-with: Cursor
1 parent 10ba227 commit 79923cd

9 files changed

Lines changed: 569 additions & 1 deletion

README.md

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Example code for using proxy servers in different programming languages. Current
44

55
* Python
66
* Ruby
7+
* PHP
78

89
## Python Proxy Examples
910

@@ -71,7 +72,76 @@ python python/run_tests.py requests-proxy-headers httpx-proxy-headers
7172

7273
## Ruby Proxy Examples
7374

74-
* [requests_proxy.rb](ruby/requests_proxy.rb) - Ruby HTTP with proxy, from [rpolley](https://github.com/rpolley)
75+
**Installation:**
76+
77+
```bash
78+
cd ruby
79+
bundle install
80+
```
81+
82+
**Running Examples:**
83+
84+
```bash
85+
# Required: Set your proxy URL
86+
export PROXY_URL='http://user:pass@proxy.example.com:8080'
87+
88+
# Run a single example
89+
ruby ruby/faraday_proxy.rb
90+
91+
# Run all examples as tests
92+
ruby ruby/run_tests.rb
93+
```
94+
95+
**Examples:**
96+
97+
| Library | Example | Description |
98+
|---------|---------|-------------|
99+
| [Net::HTTP](https://ruby-doc.org/stdlib/libdoc/net/http/rdoc/Net/HTTP.html) | [net_http_proxy.rb](ruby/net_http_proxy.rb) | Ruby standard library HTTP client |
100+
| [Faraday](https://lostisland.github.io/faraday/) | [faraday_proxy.rb](ruby/faraday_proxy.rb) | HTTP client with middleware support |
101+
| [HTTParty](https://github.com/jnunemaker/httparty) | [httparty_proxy.rb](ruby/httparty_proxy.rb) | Makes HTTP fun again |
102+
| [RestClient](https://github.com/rest-client/rest-client) | [rest_client_proxy.rb](ruby/rest_client_proxy.rb) | Simple REST client |
103+
| [Typhoeus](https://typhoeus.github.io/) | [typhoeus_proxy.rb](ruby/typhoeus_proxy.rb) | Fast HTTP client (libcurl wrapper) |
104+
| [HTTP.rb](https://github.com/httprb/http) | [http_rb_proxy.rb](ruby/http_rb_proxy.rb) | Simple Ruby DSL for HTTP |
105+
| [Excon](https://github.com/excon/excon) | [excon_proxy.rb](ruby/excon_proxy.rb) | Fast, simple HTTP(S) client |
106+
| [HTTPClient](https://github.com/nahi/httpclient) | [httpclient_proxy.rb](ruby/httpclient_proxy.rb) | LWP-like HTTP client |
107+
| [Mechanize](https://github.com/sparklemotion/mechanize) | [mechanize_proxy.rb](ruby/mechanize_proxy.rb) | Web automation library |
108+
109+
> **Note:** See [ruby-proxy-headers](https://github.com/proxymeshai/ruby-proxy-headers) for extensions that add custom proxy header support.
110+
111+
## PHP Proxy Examples
112+
113+
**Installation:**
114+
115+
```bash
116+
cd php
117+
composer install
118+
```
119+
120+
**Running Examples:**
121+
122+
```bash
123+
# Required: Set your proxy URL
124+
export PROXY_URL='http://user:pass@proxy.example.com:8080'
125+
126+
# Run a single example
127+
php php/guzzle_proxy.php
128+
129+
# Run all examples as tests
130+
php php/run_tests.php
131+
```
132+
133+
**Examples:**
134+
135+
| Library | Example | Description |
136+
|---------|---------|-------------|
137+
| [cURL](https://www.php.net/manual/en/book.curl.php) | [curl_proxy.php](php/curl_proxy.php) | PHP's built-in HTTP client (libcurl) |
138+
| [Guzzle](https://docs.guzzlephp.org/) | [guzzle_proxy.php](php/guzzle_proxy.php) | Most popular PHP HTTP client |
139+
| [Symfony HttpClient](https://symfony.com/doc/current/http_client.html) | [symfony_http_client_proxy.php](php/symfony_http_client_proxy.php) | Modern PSR-18 HTTP client |
140+
| [Buzz](https://github.com/kriswallsmith/Buzz) | [buzz_proxy.php](php/buzz_proxy.php) | Simple PSR-18 HTTP client |
141+
| [PHP Streams](https://www.php.net/manual/en/book.stream.php) | [streams_proxy.php](php/streams_proxy.php) | Built-in PHP streams (file_get_contents) |
142+
| [Amp HTTP](https://amphp.org/http-client) | [amphp_proxy.php](php/amphp_proxy.php) | Async HTTP client |
143+
144+
> **Note:** See [php-proxy-headers](https://github.com/proxymeshai/php-proxy-headers) for extensions that add custom proxy header support.
75145
76146
## Documentation
77147

php/amphp_proxy.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/usr/bin/env php
2+
<?php
3+
/**
4+
* Amp HTTP Client with proxy example.
5+
*
6+
* Configuration via environment variables:
7+
* PROXY_URL - Proxy URL (required), e.g., http://user:pass@proxy:8080
8+
* TEST_URL - URL to request (default: https://api.ipify.org?format=json)
9+
*
10+
* Amp HTTP Client is an async HTTP client for PHP. It supports proxies
11+
* but does NOT support custom CONNECT headers or reading proxy response headers.
12+
*/
13+
14+
require_once __DIR__ . '/vendor/autoload.php';
15+
16+
use Amp\Http\Client\HttpClientBuilder;
17+
use Amp\Http\Client\Request;
18+
use Amp\Http\Tunnel\Http1TunnelConnector;
19+
use Amp\Socket\SocketAddress;
20+
21+
$proxyUrl = getenv('PROXY_URL') ?: getenv('HTTPS_PROXY');
22+
if (!$proxyUrl) {
23+
fwrite(STDERR, "Error: Set PROXY_URL environment variable\n");
24+
exit(1);
25+
}
26+
27+
$testUrl = getenv('TEST_URL') ?: 'https://api.ipify.org?format=json';
28+
29+
$parsedProxy = parse_url($proxyUrl);
30+
$proxyHost = $parsedProxy['host'];
31+
$proxyPort = $parsedProxy['port'] ?? 8080;
32+
33+
try {
34+
$connector = new Http1TunnelConnector(
35+
new SocketAddress($proxyHost, $proxyPort)
36+
);
37+
38+
$client = (new HttpClientBuilder())
39+
->usingPool($connector)
40+
->build();
41+
42+
$request = new Request($testUrl);
43+
$response = $client->request($request);
44+
45+
echo "Status: " . $response->getStatus() . "\n";
46+
echo "Body: " . $response->getBody()->buffer() . "\n";
47+
} catch (Exception $e) {
48+
fwrite(STDERR, "Error: " . $e->getMessage() . "\n");
49+
exit(1);
50+
}

php/buzz_proxy.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/usr/bin/env php
2+
<?php
3+
/**
4+
* Buzz with proxy example.
5+
*
6+
* Configuration via environment variables:
7+
* PROXY_URL - Proxy URL (required), e.g., http://user:pass@proxy:8080
8+
* TEST_URL - URL to request (default: https://api.ipify.org?format=json)
9+
*
10+
* Buzz is a simple PSR-18 HTTP client. It supports proxies but does NOT
11+
* support custom CONNECT headers or reading proxy response headers.
12+
*/
13+
14+
require_once __DIR__ . '/vendor/autoload.php';
15+
16+
use Buzz\Browser;
17+
use Buzz\Client\Curl;
18+
use Nyholm\Psr7\Factory\Psr17Factory;
19+
20+
$proxyUrl = getenv('PROXY_URL') ?: getenv('HTTPS_PROXY');
21+
if (!$proxyUrl) {
22+
fwrite(STDERR, "Error: Set PROXY_URL environment variable\n");
23+
exit(1);
24+
}
25+
26+
$testUrl = getenv('TEST_URL') ?: 'https://api.ipify.org?format=json';
27+
28+
try {
29+
$psr17Factory = new Psr17Factory();
30+
31+
$client = new Curl($psr17Factory, [
32+
'proxy' => $proxyUrl,
33+
'timeout' => 30,
34+
]);
35+
36+
$browser = new Browser($client, $psr17Factory);
37+
$response = $browser->get($testUrl);
38+
39+
echo "Status: " . $response->getStatusCode() . "\n";
40+
echo "Body: " . $response->getBody() . "\n";
41+
} catch (Exception $e) {
42+
fwrite(STDERR, "Error: " . $e->getMessage() . "\n");
43+
exit(1);
44+
}

php/composer.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "proxymesh/proxy-examples-php",
3+
"description": "PHP proxy usage examples",
4+
"type": "project",
5+
"license": "MIT",
6+
"require": {
7+
"php": ">=8.1",
8+
"guzzlehttp/guzzle": "^7.8",
9+
"symfony/http-client": "^7.0",
10+
"php-http/guzzle7-adapter": "^1.0",
11+
"nyholm/psr7": "^1.8",
12+
"kriswallsmith/buzz": "^1.2",
13+
"amphp/http-client": "^5.0"
14+
},
15+
"autoload": {
16+
"psr-4": {
17+
"ProxyExamples\\": "src/"
18+
}
19+
},
20+
"scripts": {
21+
"test": "php run_tests.php"
22+
}
23+
}

php/curl_proxy.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/usr/bin/env php
2+
<?php
3+
/**
4+
* cURL with proxy example.
5+
*
6+
* Configuration via environment variables:
7+
* PROXY_URL - Proxy URL (required), e.g., http://user:pass@proxy:8080
8+
* TEST_URL - URL to request (default: https://api.ipify.org?format=json)
9+
*
10+
* cURL is PHP's built-in HTTP client. It supports proxies and has the BEST
11+
* potential for custom proxy headers via CURLOPT_PROXYHEADER (PHP 7.0.7+).
12+
* However, reading proxy CONNECT response headers is still limited.
13+
*/
14+
15+
$proxyUrl = getenv('PROXY_URL') ?: getenv('HTTPS_PROXY');
16+
if (!$proxyUrl) {
17+
fwrite(STDERR, "Error: Set PROXY_URL environment variable\n");
18+
exit(1);
19+
}
20+
21+
$testUrl = getenv('TEST_URL') ?: 'https://api.ipify.org?format=json';
22+
23+
$ch = curl_init();
24+
25+
curl_setopt_array($ch, [
26+
CURLOPT_URL => $testUrl,
27+
CURLOPT_PROXY => $proxyUrl,
28+
CURLOPT_RETURNTRANSFER => true,
29+
CURLOPT_FOLLOWLOCATION => true,
30+
CURLOPT_SSL_VERIFYPEER => true,
31+
CURLOPT_TIMEOUT => 30,
32+
]);
33+
34+
$response = curl_exec($ch);
35+
36+
if (curl_errno($ch)) {
37+
fwrite(STDERR, "Error: " . curl_error($ch) . "\n");
38+
curl_close($ch);
39+
exit(1);
40+
}
41+
42+
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
43+
curl_close($ch);
44+
45+
echo "Status: {$httpCode}\n";
46+
echo "Body: {$response}\n";

php/guzzle_proxy.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/usr/bin/env php
2+
<?php
3+
/**
4+
* Guzzle with proxy example.
5+
*
6+
* Configuration via environment variables:
7+
* PROXY_URL - Proxy URL (required), e.g., http://user:pass@proxy:8080
8+
* TEST_URL - URL to request (default: https://api.ipify.org?format=json)
9+
*
10+
* Guzzle is the most popular PHP HTTP client. It supports proxies but does NOT
11+
* support sending custom headers during HTTPS CONNECT or reading proxy response headers.
12+
*/
13+
14+
require_once __DIR__ . '/vendor/autoload.php';
15+
16+
use GuzzleHttp\Client;
17+
18+
$proxyUrl = getenv('PROXY_URL') ?: getenv('HTTPS_PROXY');
19+
if (!$proxyUrl) {
20+
fwrite(STDERR, "Error: Set PROXY_URL environment variable\n");
21+
exit(1);
22+
}
23+
24+
$testUrl = getenv('TEST_URL') ?: 'https://api.ipify.org?format=json';
25+
26+
try {
27+
$client = new Client([
28+
'proxy' => $proxyUrl,
29+
'timeout' => 30,
30+
]);
31+
32+
$response = $client->get($testUrl);
33+
34+
echo "Status: " . $response->getStatusCode() . "\n";
35+
echo "Body: " . $response->getBody() . "\n";
36+
} catch (Exception $e) {
37+
fwrite(STDERR, "Error: " . $e->getMessage() . "\n");
38+
exit(1);
39+
}

0 commit comments

Comments
 (0)