Category Archives: PHP

PHP/Apache running on Linux won’t connect to a PostgreSQL server

SELinux will block PHP/Apache from connecting to PostgreSQL (and probably any other DB) by default on some Linux distributions. If you are trying to get PHP to connect to a PostreSQL DB on a linux box for the first time and you are sure your pg_hba.conf on the target box is setup correctly then try this:

setsebool -P httpd_can_network_connect 1

This should configure SELinux to allow Apache/PHP to connect to other hosts.

Php-cgi.exe application error on IIS with FastCGI

I recently installed PHP 5.2.14 on a Windows 2003 machine running IIS 6 with FastCGI to do some PHP testing at home. I chose the fast CGI install and added several extensions during the install including Curl and Oracle. When I attempted pull a test page after the install completed, I saw the following php-cgi.exe application error on the Windows server’s desktop:

The instruction at “0x100f36ec” referenced memory at “0x000c0194″. The memory could not be “read”.

IIS sent the following error message back to the requesting browser after a couple minutes:

FastCGI Error
The FastCGI Handler was unable to process the request.

Error Details:

* The FastCGI process exited unexpectedly
* Error Number: -1073741819 (0xc0000005).
* Error Description: Unknown Error

HTTP Error 500 – Server Error.
Internet Information Services (IIS)

After some trial and error I was able to get my test page to display if I commented the “extension=php_curl.dll” and “extension=php_oci8.dll” lines in my php.ini file:

; Local Variables:
; tab-width: 4
; End:
[PHP_CURL]
;extension=php_curl.dll
[PHP_GD2]
extension=php_gd2.dll
[PHP_MSQL]
extension=php_msql.dll
[PHP_MSSQL]
extension=php_mssql.dll
[PHP_MYSQL]
extension=php_mysql.dll
[PHP_MYSQLI]
extension=php_mysqli.dll
[PHP_OCI8]
;extension=php_oci8.dll
[PHP_PDO]
extension=php_pdo.dll
[PHP_PGSQL]
extension=php_pgsql.dll
[PHP_SHMOP]
extension=php_shmop.dll
[PHP_SOAP]
extension=php_soap.dll
[PHP_SQLITE]
extension=php_sqlite.dll
[PHP_XMLRPC]
extension=php_xmlrpc.dll

After some more trial error I was unable to get PHP to work without leaving the two lines commented. I tried both the VC6 thread and VC6 non thread safe versions and both exhibited the same behavior. On the PHP download page there is a “Which version do I choose?” section that basically explains that I should be using the VC9 version for IIS. Unfortunately I only saw the PHP 5.3.3 VC9 download and I wanted to test with PHP 5.2.14.

I downloaded PHP 5.3.3 anyway and it worked. I guess I will be testing with PHP 5.3.3.

On a somewhat related note, if you are using FastCGI with IIS, you will probably want the VC9 PHP 3.3.3 non thread safe version. This article explains why.

How to get the contents of an Oracle CLOB data field in PHP

The Oracle “CLOB” (Character Large Object) is a data type used to store up to 4 Gigabytes of text. Retrieving the contents of a CLOB is not as intuitive as you might think.

Let’s say you have a CLOB field/column named “mychars” in an Oracle DB table named “mytable” along with some other fields. You want to simply echo out the text in the “mychars” field:

<?php
    $id = '3';
    $conn = oci_connect('myusr', 'mypass', 'mydb');
    if (!$conn){
        echo 'Connection error.';
    }
    $sql = 'SELECT * FROM mytable WHERE myid=:id';
    $stid = oci_parse($conn, $sql);
    oci_bind_by_name($stid, ":id", $id);
    $result = oci_execute($stid);
    if($result !== false){
        while($row = oci_fetch_assoc($stid)){
            echo $row['mychars'];
        }
    }
?>

The above code will give you an error that looks like the following:

Catchable fatal error: Object of class OCI-Lob could not be converted to string in somefile.php on line 14

If you try to do a print_r() on the CLOB in an attempt to figure out what you are dealing with you will get something that looks like:

OCI-Lob Object ( [descriptor] => Resource id #3 )

This is because a Lob object is returned instead of the contents of the CLOB.

To get the CLOB contents you will need to call the load() or read() methods on the returned object. The latter will require the length of data to read in bytes but has the advantage of not being limited by the script memory limit:

<?php
    $id = '24382';
    $conn = oci_connect('myusr', 'mypass', 'mydb');
    if (!$conn){
        echo 'Connection error.';
    }
    $sql = 'SELECT * FROM mytable WHERE myid=:id';
    $stid = oci_parse($conn, $sql);
    oci_bind_by_name($stid, ":id", $id);
    $result = oci_execute($stid);
    if($result !== false){
        while($row = oci_fetch_assoc($stid)){
            echo $row['mychars']->load();
            //or
            echo $row['mychars']->read(2000);
        }
    }
?>

How to use the PHP cURL module to make HTTP requests from PHP

Some of my previous posts talked about making HTTP/web requests from PHP with a focus on the PECL_HTTP request module:

The last post mentioned above covered using the built-in file_get_contents() as an alternative if you are unable to install the HTTP PECL extension or need minimal HTTP functionality. This post will look at a third method of making HTTP requests from PHP, using the PHP Client URL Library AKA cURL library. The PHP cURL library essentially uses the cURL library from the cURL command line utility and makes the calls available via PHP functions.

Installing the PHP cURL library on Ubuntu requires just a couple simple steps:

  • PHP needs to compile in the cURL library but if you are using Ubuntu you can simply execute the following shell command instead of doing a custom PHP build:
    sudo apt-get install php5-curl
  • Restart Apache once the library has installed.
  • Call a page with the phpinfo() function and look for a “curl” section. It should be listed there if everything installed correctly:

    curlinfo1

Once the cURL library is added you can call the curl functions which are documented here. The following simple example makes a call to www.example.com. You will notice that I did not “echo” the return of curl_exec() to display it. This is because by default, the curl_exec() function displays the result and returns a true on success, false on failure.

<?php
 
$curl_handle = curl_init("http://www.example.com/");
curl_exec($curl_handle);
curl_close($curl_handle);
 
?>

If you want to assign the output to a variable so you can do something with it, you will need to set the CURLOPT_RETURNTRANSFER option:

<?php
 
$curl_handle = curl_init("http://www.example.com/");
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);
$results = curl_exec($curl_handle);
curl_close($curl_handle);
echo $results;
 
?>

The PHP cURL library has a variety of options you can set using the curl_setopt() function. This includes setting GET and POST requests, setting fields for each, etc.

That is the five minute version of the PHP cURL library. Another quick way to make an HTTP request is to just make a system call to the “wget” command utility which is included on most *nix systems:

<?php
 
echo system("wget -O - http://www.example.com");
 
?>

This pretty cool but I think I prefer the other methods because they all run under the Apache process. That’s it for this post!

How to setup and use the Xdebug Extension for PHP Profiling

A profiling tool can provide valuable information about bottlenecks in your code. I believe profiling is a critical aspect of optimizing because it will tell you about your real code bottlenecks as opposed to your perceived bottlenecks. This enables you to focus your resources on areas that will provide the most performance benefit for your effort. Most programming languages and environments have one or more profiling tools available and PHP is no exception.

Xdebug is a PHP extension that provides valuable debugging information such as stack traces, functions traces, profiling, code coverage analysis, etc. There is another PHP tool called DBG that has similar functionality but this post will focus on using Xdebug.

Setup Xdebug

Xdebug is a PECL module and can be installed using the PECL installation instructions in one of my previous posts.

  • If you have already setup PEAR you just need to run the following from a shell:
    sudo pecl install xdebug

    If everything goes well Xdebug should download, build, and install. You may get a message telling you:

    You should add "extension=xdebug.so" to php.ini

    Go ahead and add the line. On an Ubuntu server you will probably find the php.ini file here: /etc/php5/apache2/php.ini

  • Restart Apache, or whatever web server you are using, so the change will take effect.
    If you are running Apache on Ubuntu it would be:

    sudo /etc/init.d/apache2 restart
  • Write a phpinfo.php page with the following code and then point a browser at it. It should show the Xdebug module there in addition to many other things:
    <?php phpinfo(); ?>

At this point the Xdebug extension should be installed. For more detailed instructions on a PECL extension install see my post: How to install a PHP PECL extension/module on Ubuntu. Note that there is a problem running the Xdebug extension with Zend Studio since it has it’s own debugger.

Enable Xdebug profiling

  • By default, profiling is disable in Xdebug. Enable it by adding the following entry to the php.ini file:
    xdebug.profiler_enable=On

    On on a linux box there is often a php.d or conf.d folder that holds additional .ini file settings PHP will use. On Ubuntu the path for this folder is “/etc/php5/apache2/conf.d”. To prevent further cluttering my php.ini file with Xdebug settings, I created a xdebug.ini file to store all my Xdebug .ini file settings. This file is located in the “/etc/php5/apache2/conf.d” so it is automatically scanned when Apache is restarted.

    Now you might be tempted to enable the profiler in your script using the ini_set() function which, normally allows you to temporarily set a .ini setting for only the current script execution. Unfortunately this does not work. You must set it in the php.ini or a sub .ini file and restart the web server.

  • Restart your web server (I.e. Apache) once you have “xdebug.profiler_enable” set to “On”.

By default, Xdebug will write a cachegrind.out file to the /tmp folder. It will be named something like cachegrind.out.22373 where the number at the end is the ID of the process that was profiled. If you are using Windows you will probably need to change the default folder. Also by default, this file will be overwritten by each script execution so you don’t have to worry about it getting too big. The output file behavior is highly customizable and a complete list of Xdebug settings can be found here.

Call your script and display the analysis

With Xdebug enabled, pull up the page in your browser that you want to profile. If everything is working OK a cachegrind.out file should show up in the /tmp folder.

There are a couple programs you can use to open and analyze the cachegrind file:

WinCacheGrind

WinCacheGrind is not very featured but it will tell you the main thing you need to know, which is where your PHP application is spending its time. Click on the screen shot below to see the full output of my test script:

wincachegrind screen shot

The script makes an external call to example.com using a file_get_contents() function. Based on this analysis I might try caching the call results and only make the call at some interval to keep the cache updated. This would eliminate almost 75% of the application’s overhead and is just one example of an easy-to-fix bottleneck that profiling will help identify.

KCacheGrind

KCacheGrind does essentially the same thing as WinCacheGrind but it is geared for the Linux desktop and has quite a few more bells and whistles:

kcachegrind screen shot

KCacheGrind includes a map feature that graphically represents the percentages of where the test application spent the time:

kcachegrind screen shot

KCacheGrind also includes a graph feature with an export option that displays a tree diagram of the linkage between all the includes and functions:

kcachegrindexport1.jpg

That’s it for this post. Have fun profiling!