Category Archives: PHP

How to use the PECL HTTP (PECL_HTTP) Extension to make HTTP requests from PHP

PECL HTTP is a feature-rich PHP extension that allows you to make HTTP and HTTPS (SSL) requests from your PHP code and handle the responses. If you are not familiar with PECL, it is a library of extensions to add functionality to PHP. It uses the same package and delivery system as PEAR.

Many distributions do not install PECL_HTTP by default even if you install PHP. If you try to use one of the PECL_HTTP object or functions (I.e. http_get()) without the extension installed you will likely get something like this:

Fatal error: Call to undefined function http_get()

If this error comes up but you think you installed the PECL_HTTP package and it shows up in phpinfo(), then it is possible your PECL_HTTP install failed and did not get cleaned up so phpinfo() still sees it. This may happen if you didn’t install the cURL source library dependency first (see below).

So let’s pretend we own the site http://www.example.com (See RFC 2606.) We want to build a PHP diagnostic page that will tell us that www.example.com is returning the string “example” somewhere in the page indicating if the page is up or down. First I need to install the PECL_HTTP extension. For details on how to install a PECL extension see my post “How to install a PHP PECL extension/module on Ubuntu“. For now I am going to assume that the php-pear and php5-dev packages have already been installed. These instructions are based on a Ubuntu install:

  • Install the libcurl3-openssl-dev package. The HTTP_PECL extension requires some of the cURL source libraries so we will have to install the cURL library package first:
    sudo apt-get install libcurl3-openssl-dev

    If you don’t install the cURL source library package you will likely see the following error when you attempt to install the PECL_HTTP extension:

    checking for curl/curl.h... not found
    configure: error: could not find curl/curl.h
    ERROR: ‘/tmp/pear/temp/pecl_http/configure --with-http-curl-requests --with-http-zlib-compression=1 --with-http-magic-mime=no --with-http-shared-deps’ failed
  • Install the HTTP_PECL module with the following command:
    sudo pecl install pecl_http

    The installer may ask you about some specific options but unless you really know what you want, you can probably just hit enter one or more times to accept all the defaults. If all goes well, the module should download, build, and install.

  • Once the install is complete, it will probably ask you to add a “extension=http.so” line to your php.ini file. Open up the php.ini file in your favorite text editor and add the line under the section labeled “Dynamic Extensions”. On Ubuntu the php.ini file seems to be located in the /etc/php5/apache2 folder:
    sudo nano /etc/php5/apache2/php.ini
  • Now that the php.ini file has been updated, Apache will need to be restarted so the new extension will be loaded:
    sudo /etc/init.d/apache2 restart

    That should restart Apache on Ubuntu but if that doesn’t work you can try:

    sudo /etc/init.d/httpd restart

At this point hopefully the PECL_HTTP extension is installed so now we can create a PHP script that will make an HTTP request to http://www.example.com and display the results. For this example I will use the http_get() function. The first argument is a predefined constant of the request method type (GET, POST, etc.) and the second argument is a string containing the URL. I created a file named httptest.php (using “sudo nano /var/www/httptest.php” with the following code and put it in the /var/www folder (The default HTTP root on a Ubuntu server):

<?php

echo http_get("http://www.example.com");

?>

or you could use the http_request function instead to do the same thing:

<?php

echo http_request(HTTP_METH_GET,"http://www.example.com");

?>

When the page is opened in a web browser (I.e. http://sparky/httptest.php) it returns something like this:

HTTP/1.1 200 OK Date: Sun, 04 Jan 2009 22:41:54 GMT Server: Apache/2.2.3 (CentOS) Last-Modified: Tue, 15 Nov 2005 13:24:10 GMT ETag: "b80f4-1b6-80bfd280" Accept-Ranges: bytes Content-Length: 438 Connection: close Content-Type: text/html; charset=UTF-8

You have reached this web page by typing "example.com", "example.net", or "example.org" into your web browser.

These domain names are reserved for use in documentation and are not available for registration. See RFC 2606, Section 3.

That’s it. Those are some pretty quick one-liners if we are fine with the default options. This time we’ll do something similar but use the HttpRequest object instead and set a timeout and a different user agent:

<?php

$http_req = new HttpRequest("http://www.example.com");
$http_req->setOptions(array(timeout=>10,useragent=>"MyScript"));
$http_req->send();
echo $http_req->getRawResponseMessage();

?>

The output is the same as the previous two commands but this time the server could have taken up to ten seconds to respond before the request timed out. In addition, we sent the user agent string “MyScript” in the host header to the server. If you don’t want the HTTP response headers included in the the output, you use the getResponseBody() method instead:

<?php

$http_req = new HttpRequest("http://www.example.com");
$http_req->setOptions(array(timeout=>10,useragent=>"MyScript"));
$http_req->send();
echo $http_req->getResponseBody();

?>

This outputs:

You have reached this web page by typing "example.com", "example.net", or "example.org" into your web browser.

These domain names are reserved for use in documentation and are not available for registration. See RFC 2606, Section 3.

No response headers this time. In fact, it looks as though you typed http://www.example.com in the browser.

I could set some URL query parameters using the setQueryData() if example.com was a dynamic page that accepts arguments but I am pretty sure it does not.

For the purpose of our example it doesn’t look like we have gotten very far but PHP is now getting a hold of the response data before we see it so we are halfway there. Now all we need to do is search for the string “example” and return some type of indicator letting us know that the example.com page is up or down:

<?php

$http_req = new HttpRequest("http://www.example.com");
$http_req->setOptions(array(timeout=>10,useragent=>"MyScript"));
$http_req->send();

/*Note: The stripos() function just returns false if it doesn't find an upper or lower case version of the string we are looking for.*/
if (!stripos($http_req->getResponseBody(), "example")){
    echo "The page is down!";
} else {
    echo "The page is up!";
}

?>

If everything is working correctly we will see:

The page is up!

If example.com is broken or doesn’t return the string “example” our test page returns:

The page is down!

This is great and all but you may have noticed there is no error handling to speak of which isn’t good. I will talk about HTTP request/PECL_HTTP error handling in a separate post but until then, happy HTTPing!

How to install a PHP PECL extension/module on Ubuntu

PHP PECL extensions provide additional functionality over the base PHP install. You can browse the PHP PECL extensions available at the PECL repository here. The following steps show how to install a PECL extension/module on Ubuntu using the PECL_HTTP extension as an example and assumes that you already have Apache 2 and PHP 5 installed:

  • First, you will need to install PEAR via apt-get to get the necessary package and distribution system that both PEAR and PECL use. From a shell prompt enter:
    sudo apt-get install php-pear

    You will be prompted to confirm the install. Just press “y” and enter. If all goes well you should see it download and install the php-pear package.

    Note: “sudo” is used to provide the super user privileges necessary for the following command. So in this case the command “apt-get install php-pear” is being executed with super user privileges by preceding it with “sudo”. Unless configured otherwise, you will normally be prompted to enter a password when you use sudo. This is usually the same password that you logged in with.
  • Now you will need to install the php5-dev package to get the necessary PHP5 source files to compile additional modules. Enter the following from a shell prompt:
    sudo apt-get install php5-dev

    If you do not install the php5-dev package and try to install a PECL extension using “pear install”, you will get the following error:

    sh: phpize: not found
    ERROR: `phpize’ failed
  • The PECL_HTTP extension requires an additional dependency package to be installed. You can probably skip this for other extensions:
    sudo apt-get install libcurl3-openssl-dev
  • Now we are finally ready to actually install the extension. From a shell prompt enter following but substitute “pecl_http” with the PECL extension name you are installing:
    sudo pecl install pecl_http

    The installer may ask you about some specific options for the extension you are installing. You can probably just hit enter one or more times to accept all the defaults unless you want to set specific options for your implementation. If all goes well, the module should download, build, and install.

  • Once the install is complete, it will probably ask you to add a “extension=” line to your php.ini file. Open up the php.ini file in your favorite text editor and add the line under the section labeled “Dynamic Extensions”. On Ubuntu the php.ini file seems to be located in the /etc/php5/apache2 folder:
    sudo nano /etc/php5/apache2/php.ini

    In this example, the pecl_http extension install asked me to add “extension=http.so”.

  • Now that the php.ini file has been updated, Apache will need to be restarted so the new extension will be loaded:
    sudo /etc/init.d/apache2 restart

    That should restart Apache on Ubuntu but if that doesn’t work you can try:

    sudo /etc/init.d/httpd restart

If all went well your PECL extension should now be working. You might want to write a PHP test page that will test the basic functionality of the extension to make sure everything is working OK. You can use this later to check that all your required extensions are installed and working when you deploy to a new server. In this example where I installed the PECL_HTTP module, I might write a PHP page that uses the extension’s HttpRequest class to go get a page and return the results.

That’s it. For the next extension install you can skip the steps to install the php-pear and php5-dev packages.