34

I'm behind a proxy server that does not allow a direct connection to internet. All of my PHP applications fail to connect to internet for their update checks and etc.

How can I tell PHP my Proxy Settings?

I don't want to enter proxy settings into the code, I want PHP itself use it via a global config setting or something similar.

Mark Amery
  • 143,130
  • 81
  • 406
  • 459
Alexar
  • 1,858
  • 5
  • 24
  • 34

8 Answers8

19

if almost all of you internet access need a proxy, I'd prefer do like this.

//add this as the first line of the entry file may it is the index.php or config.php
stream_context_set_default(['http'=>['proxy'=>'proxy-host:proxy-port']]);

the proxy will work for file_get_contents but not curl_exec

here is a official document.

kubanczyk
  • 5,184
  • 1
  • 41
  • 52
Ian Hu
  • 295
  • 3
  • 7
  • 1
    sorry for my mistake, the stream api is not affect the curl, if you use curl, you'd better set it by `curl_setopt($handle, CURLOPT_PROXY, $proxy_url);`, and if you use both, you can add both two. – Ian Hu Aug 24 '16 at 01:49
  • I couldn't get it work with a proxy server that has password – Tarik Aug 31 '17 at 16:15
  • 2
    @Tarik if your proxy server need a basic authentication, your need to do it like this `stream_context_set_default(['http'=>['proxy'=>'proxy-host:proxy-port', 'header'=>'Proxy-Authorization: Basic '.base64_encode('your-username:your-password')]]);` – Ian Hu Mar 13 '18 at 03:11
  • @Tarik the key point is the `Proxy-Authorization` header, you can find more information at [@pascal-martin 's answer](https://stackoverflow.com/a/1336419/4045767) – Ian Hu Mar 13 '18 at 03:17
  • @IanHu Thanks, I found my solution with this code: '$curlProxy = array( 'http'=>array( 'method'=>"GET", 'header'=>"Proxy-Authorization: Basic AUTH_CODE_HERE==\r\n" . "Proxy-Connection: Keep-Alive", 'proxy'=>"IP_ADDRESS:PORT" ) );' – Tarik Mar 13 '18 at 08:54
13

This depends on how your PHP application connects to the internet.

If taking the most likely situation using PHP cUrl. In that case the following options will help you:

curl_setopt($handle, CURLOPT_PROXY, $proxy_url); 
curl_setopt($handle, CURLOPT_PROXYUSERPWD, "[username]:[password]"); 

See also: http://www.php.net/manual/en/function.curl-setopt.php

Tramov
  • 1,166
  • 1
  • 11
  • 17
  • 1
    thanks for the answer. but consider that this may be applied just for my own codes. what about other PHP applications like Drupal? I need PHP itself connect through Proxy not via the code. – Alexar Mar 24 '11 at 10:00
6

Sample code:

function getUrl($url)
{
    $ch = curl_init(); 
    $timeout = 5; // set to zero for no timeout 
    curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout); 
    curl_setopt ($ch, CURLOPT_URL, $url); 
    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_PROXY, "http://proxy.example.com"); //your proxy url
    curl_setopt($ch, CURLOPT_PROXYPORT, "8080"); // your proxy port number 
    curl_setopt($ch, CURLOPT_PROXYUSERPWD, "username:pass"); //username:pass 
    $file_contents = curl_exec($ch); 
    curl_close($ch); 
    return $file_contents;
}

echo  getUrl("http://www.google.com");
Evan Lee
  • 738
  • 15
  • 36
3

Yes it's possible!

You can configure stream_context_set_default in a file, and include this file in all your Php program, by using auto_prepend_file php.ini property.

I wrote a small gist about:

https://gist.github.com/ebuildy/381f116e9cd18216a69188ce0230708d

And an article in french:

https://medium.com/@thomasdecaux/param%C3%A9trer-par-d%C3%A9faut-un-proxy-pour-php-file-get-content-3e9a32416979#.6zbg605cx

This technique is "cool" because, this allows your sys-admin to configure the host, so developer don't have to change anything in the code.

Thomas Decaux
  • 21,738
  • 2
  • 113
  • 124
2

I searched over the internet and could not find anything about stream_context_set_default() with a password protected proxy server.

Then I thought that password in basic authorization is sent in headers. So I modified the headers with the password extracted from a CURL request and it worked perfect!!!

Here is how you do it:

First send this request to any domain (example.com) as below:

curl -v -U user:pass -x your_proxy_ip:port --url https://example.com

See the curl sent headers and I got these proxy lines to use later:

>   Trying XXX.XXX.XXX.XXX...
> Connected to XXX.XXX.XXX.XXX (XXX.XXX.XXX.XXX) port YYYY (#0)
> Establish HTTP proxy tunnel to example.com:443
> Proxy auth using Basic with user 'your_username_here'
> CONNECT example.com:443 HTTP/1.1
> Host: example.com:443
> Proxy-Authorization: Basic YW1hem9uOnXXXXXXXXXXXXXXX25SMg
> User-Agent: curl/7.47.0
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 Connection established
<
< Proxy replied OK to CONNECT request

OK now it is time to build our custom header:

$default_opts = array(
  'http'=>array(
    'method'=>"GET",
    'header'=>"Proxy-Authorization: Basic YW1hem9uOnXXXXXXXXXXXXXXX25SMg\r\n" .
              "Proxy-Connection: Keep-Alive",
    'proxy'=>"XXX.XXX.XXX.XXX:YYYY"
  )
);

$default = stream_context_set_default($default_opts);


$result = file_get_contents("https://ipleak.net/json/");
print_r(json_decode($result));

And it works perfect, you get the IP of your proxy server in response!

Tarik
  • 4,270
  • 38
  • 35
1

I use the PEAR HTTP_Request2 module.

Here is a simplified version of my UrlOpen() function:

function UrlOpen($url)
{
  $request = new HTTP_Request2($url);

  $request->setConfig(array(
    'proxy_host' => '192.168.1.6',
    'proxy_port' => 8080,
    'proxy_user' => 'MYUSER',
    'proxy_password' => 'MYPASS',
    'ssl_verify_peer' => False,
    'connect_timeout' => 3,
  );

  return $request;
}

$req = UrlOpen($url);
$res = $req->send();
if ($res->getStatus() == '200')
  $data = $request->getBody();
Martin Tournoij
  • 26,737
  • 24
  • 105
  • 146
0

For Drupal you can set proxy configuration in your settings.php file.

$conf['proxy_server'] and so on.

More details here

Jokerius
  • 1,310
  • 1
  • 14
  • 22
0

For some scripts, all you have to do is set the environment variable HTTP_PROXY. That was the case for both composer.phar and media-wiki's maintenance/update.php scripts.

E.g.:

setenv HTTP_PROXY http://1.2.3.4:3934

If your proxy is at 1.2.3.4 listening on port 3934. Worked for me.

kenorb
  • 155,785
  • 88
  • 678
  • 743
rustycar
  • 33
  • 5