79

At work we have to use a proxy to basically access port 80 for example, we have our own custom logins for each user.

My temporary workaround is using curl to basically login as myself through a proxy and access the external data I need.

Is there some sort of advanced php setting I can set so that internally whenever it tries to invoke something like file_get_contents() it always goes through a proxy? I'm on Windows ATM so it'd be a pain to recompile if that's the only way.

The reason my workaround is temporary is because I need a solution that's generic and works for multiple users instead of using one user's credentials (I've considered requesting a separate user account solely to do this but passwords change often and this technique needs to be deployed throughout a dozen or more sites). I don't want to hard-code credentials basically to use the curl workaround.

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
meder omuraliev
  • 183,342
  • 71
  • 393
  • 434

4 Answers4

182

To use file_get_contents() over/through a proxy that doesn't require authentication, something like this should do :

(I'm not able to test this one : my proxy requires an authentication)

$aContext = array(
    'http' => array(
        'proxy'           => 'tcp://192.168.0.2:3128',
        'request_fulluri' => true,
    ),
);
$cxContext = stream_context_create($aContext);

$sFile = file_get_contents("http://www.google.com", False, $cxContext);

echo $sFile;

Of course, replacing the IP and port of my proxy by those which are OK for yours ;-)

If you're getting that kind of error :

Warning: file_get_contents(http://www.google.com) [function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.0 407 Proxy Authentication Required

It means your proxy requires an authentication.

If the proxy requires an authentication, you'll have to add a couple of lines, like this :

$auth = base64_encode('LOGIN:PASSWORD');

$aContext = array(
    'http' => array(
        'proxy'           => 'tcp://192.168.0.2:3128',
        'request_fulluri' => true,
        'header'          => "Proxy-Authorization: Basic $auth",
    ),
);
$cxContext = stream_context_create($aContext);

$sFile = file_get_contents("http://www.google.com", False, $cxContext);

echo $sFile;

Same thing about IP and port, and, this time, also LOGIN and PASSWORD ;-) Check out all valid http options.

Now, you are passing an Proxy-Authorization header to the proxy, containing your login and password.

And... The page should be displayed ;-)

robsch
  • 9,358
  • 9
  • 63
  • 104
Pascal MARTIN
  • 395,085
  • 80
  • 655
  • 663
  • Martin, I have a proxy auto config (pac) file instead of single proxy server. Also it requires NTLM authentication. Can you please help me out here. – codeomnitrix Aug 27 '13 at 06:26
  • I get the following error: failed to open stream: Unable to find the socket transport "http" - did you forget to enable it when you configured PHP? I'm using PHP5.5/Apache2.4 with curl enabled. – Tuan Anh Hoang-Vu Aug 11 '14 at 14:21
  • Thank you a lot. Usually cURL satisfies me, but im experimenting with Appengine PHP, and do not has cURL laode, so file_get_content with stream context has saved me :D – m3nda Oct 28 '14 at 04:11
  • @codeomnitrix, maybe a little late, but I had the same problem and I pasted the url of the pac file in a browser and in the file I could find the proxy IP address. – Martin Lietz Feb 05 '18 at 18:33
  • 1
    For anyone: in my case it was also necessary to use `tcp` as protocol. Before I used `http` what gave me the error: _failed to open stream: Unable to find the socket transport "http" - did you forget to enable it when you configured PHP?_ – robsch Aug 01 '19 at 09:29
  • If someones gets a `400 Bad Request` using this, try to disable the non-standard `request_fulluri`. – Trendfischer Mar 02 '21 at 08:06
24

Use stream_context_set_default function. It is much easier to use as you can directly use file_get_contents or similar functions without passing any additional parameters

This blog post explains how to use it. Here is the code from that page.

<?php
// Edit the four values below
$PROXY_HOST = "proxy.example.com"; // Proxy server address
$PROXY_PORT = "1234";    // Proxy server port
$PROXY_USER = "LOGIN";    // Username
$PROXY_PASS = "PASSWORD";   // Password
// Username and Password are required only if your proxy server needs basic authentication

$auth = base64_encode("$PROXY_USER:$PROXY_PASS");
stream_context_set_default(
 array(
  'http' => array(
   'proxy' => "tcp://$PROXY_HOST:$PROXY_PORT",
   'request_fulluri' => true,
   'header' => "Proxy-Authorization: Basic $auth"
   // Remove the 'header' option if proxy authentication is not required
  )
 )
);

$url = "http://www.pirob.com/";

print_r( get_headers($url) );

echo file_get_contents($url);
?>
Pirob.com
  • 307
  • 3
  • 3
  • Very late comment I know, but **don't use `stream_context_set_default`**: it will affect the entire PHP server, possibly breaking other libraries making use of http stream wrapper. – Christian Oct 04 '22 at 12:11
3

Depending on how the proxy login works stream_context_set_default might help you.

$context  = stream_context_set_default(
  array(
    'http'=>array(
      'header'=>'Authorization: Basic ' . base64_encode('username'.':'.'userpass')
    )
  )
);
$result = file_get_contents('http://..../...');
VolkerK
  • 95,432
  • 20
  • 163
  • 226
2

There's a similar post here: http://techpad.co.uk/content.php?sid=137 which explains how to do it.

function file_get_contents_proxy($url,$proxy){

    // Create context stream
    $context_array = array('http'=>array('proxy'=>$proxy,'request_fulluri'=>true));
    $context = stream_context_create($context_array);

    // Use context stream with file_get_contents
    $data = file_get_contents($url,false,$context);

    // Return data via proxy
    return $data;

}
alex
  • 479,566
  • 201
  • 878
  • 984
Paul
  • 21
  • 1