PHP's built in HTTP client

Related:

Jekyll as a replacement for SSI

PHP has an excellent set of file system functions. Many of them closely resemeble their C counter parts but there is a big difference. The C fopen will only allow you to open local files (there are exceptions), on the other hand the PHP version can be used to open remote files too. This is made possible by the many different protocol wrappers available in PHP. There are wrappers for HTTP, HTTPS, FTP and even SSH. You can create your own as well. These wrappers makes life so easy for programmers. To fetch the contents of a web page takes just one line of code

<'? echo file_get_contents("http://www.deadlinedue.com/"); ?>

Suppose you have a remote web application that will produce a new line (\n) separated file as it's output, the code for retrieving it and loading it into an array is still a one liner

<'? print_r(file_get_contents("http://www.deadlinedue.com/")); ?>
What if you wanted more control? What if your web application returned an XML or a CSV as it's output? CSV can be handled in just four lines.

$fp = fopen("http://clients/sample.csv","r"); while ($data = fgetcsv($fp, 1000, ",")) { echo "{$data[0]}\n"; }

For XML you need not look any further than the SAX parser sample code, which demonstrates how the file hande from fopen can be used by the SAX parser. Alternatively you can use file_get_contents again to read the data into a string and pass that as input for SimpleXML. So in short fetching a web page is easy. How about posting data to a script or a servlet (HTTP POST method). Can't we make use of file_put_contents or perhaps fopen with the 'w' flag? Unfortunately both these functions will generate errors:

<'? file_put_contents("http://www.deadlinedue.com/","data=hello+world"); ?>

will produce :

PHP Warning: file_put_contents(http://www.deadlinedue.com/): failed to open stream: HTTP wrapper does not support writeable connections in /dev/shm/test.php on line 2 PHP Stack trace: PHP 1. {main}() /var/www/raditha/test.php:0 PHP 2. file_put_contents() /var/www/raditha/test.php:2

All is not lost. We can still make use of the fsockopen method to manually open a connection to the server and post the content. But we do that, we are not making use of the PHP HTTP URL Wrapper anymore.

$sock = fsockopen("www.deadlinedue.com",80,$errno,$errstr,30); if($sock) { fwrite($sock, "POST / HTTP/1.0\r\n"); fwrite($sock, "Content-length: 29\r\n"); fwrite($sock, "Content-Type: application/x-www-form-urlencoded\r\n"); fwrite($sock, "\r\n"); fwrite($sock, "lookfor=kat+bitha&find=find\r\n"); } while(! feof($sock)) { echo fgets($sock,1024); }

The above code, will open a socket connection to the webserver on deadlinedue.com and post a small amount of data and read the response. The code has many short comings. It does not separate the headers from the message body. The header often contains information required to process the message body (eg encoding or HTTP redirects), so we might find the code breaking against a different server. We will soon look at how we can implement a full featured HTTP client in PHP that supports both HTTP GET and POST.

Copyright © Raditha Dissanayake 2013