Monthly archives: December 2014

Proxy outgoing connections via PHP

Posted on December 6, 2014 Comments

For a variety of reasons, you may want to proxy all outgoing connections made by PHP’s file opening wrappers. This includes functions like file_get_contents, fopen, and readfile. If you are looking for a way to do this in php.ini/configuration, it is not possible.  As a work around, you can use the following method.

Create a PHP file with the following called set_proxy.php, changing the ‘proxy’ key to lead to a valid proxy address. Using stream_context_set_default the proxy is forced upon all the requests.

Now in PHP.ini, add the following:

This will automatically include the set_proxy.php file everywhere every time PHP runs, thus enabling your proxy for outgoing connections.

Unfortunately there are some some serious caveats if you were hoping to use this for complete and total coverage: you cannot reliably depend on this to catch all outgoing connections for every function; just the main ones. An example of this would be the getimagesize function which can be used remotely on images. During my testing I discovered this function does not listen to stream context settings at all and I have not found a way to customize it. Unsure if this is a bug or not so I have not reported it. I needed this function to be proxied and had to come up with the following workaround (only works on PHP 5.4.x =>) by using file_get_contents to download the file and then examine it with getimagesizefromstring.

Another area that that has a similar issue is within libXML; it has its own stream context function: libxml_set_streams_context. In the example set_proxy.php file, you would need to add libxml_set_streams_context($stream_default_opts); to the bottom of the file if you wanted to proxy functions within this library.

There may be other areas of PHP where you will have to specify stream context, or a function that allows remote HTTP calls doesn’t listen to the proxy configuration. So, if you are doing remote HTTP calls and it is important that you proxy the connection, then be careful and test/verify that your proxy settings are actually working for the functions you are using since you cannot just assume that setting the stream context will cover it.