PHP4 is now masked - PHP migration how to

So as most of you already know, PHP4 is now masked in portage. It' will reach end of life upstream at the end of the year. You can read more about the "PHP 4 end of life announcement".

Most of you know me as a server administrator, but I'm also heavily involved with developing PHP applications for myself or clients. So this move, is a big on in my eye. Now, for the most part, the transition from PHP4 to PHP5 is fairly simple, but I do a lot of XML web service calls, custom error handling, and use specialized extensions in some of my apps. First, I'll discuss my procedure for upgrading 4 to 5, and then show a few issues with code changes.

To keep portage from wanting to upgrade to 5 in the past, I masked it. So the first step was to remove that mask so I can get 5. After doing so, portage will bring down the latest PHP for me.

emerge -pv php

The nice einfo gave me the following instructions to configure my system to use the new PHP:

php-select apache2 php5
php-select php php5
php-select php-devel php5

We now need to reinstall PEAR-PEAR so it uses the new PHP5 path:

emerge -v PEAR-PEAR

After that is built, we need to clean out the PHP and additional dev-php4 packages (remember, these are on my system, please remove appropriate packages for your system):

emerge -C php-4.4.8_pre20070816
emerge -C pecl-fileinfo
emerge -C pecl-sqlite-1.0.3-r1
emerge -C dev-php4/jpgraph-1.21b
emerge -C dev-php4/eaccelerator
emerge -C dev-php4/adodb-4.94
emerge -c dev-php4/suhosin

Then bring in the appropriate dev-php5 packages:

emerge -v dev-php5/pecl-fileinfo
emerge -v dev-php5/jpgraph
emerge -v dev-php5/eaccelerator
emerge -v dev-php5/adodb-4.94
emerge -v dev-php5/suhosin

Please remember that PHP5 will bring in a new php.ini, so any modifications to your old php.ini file will need to be added here. Location of the php.ini file will be in /etc/php/apache2-php5/php.ini. This also applies to any PHP5 extensions with configurations (eaccelerator, suhosin, etc).

Make sure you check your apache configuration before restarting.

apache2ctl configtest
/etc/init.d/apache2 restart

Now, I mentioned that I had some coding issues. I'll address a few here, but I would imagine none of these would apply to you.

pecl-fileinfo - I use fileinfo to verify the 'true' mime type of uploaded files before accepting them. I do NOT rely on the $_FILES array for info, since this is provided by the browser. You cannot trust the client.

In PHP4, I would use the following:

$res = finfo_open(FILEINFO_MIME);
$tmpMIME = finfo_file($res,$testFile);
$tmpArr = explode(";", $tmpMIME);
finfo_close($res);

But in PHP5, you need to use the OOP method:

$fi = new finfo(FILEINFO_MIME);
$tmpMIME = $fi->file($testFile);
$tmpArr = explode(";", $tmpMIME);
unset($fi);

error handling - I use a custom error handling class, since I want to handle what the user sees. I obviously don't want to display the error message, so I disable that in the php.ini, but I want to give them a layout that indicates a error happened, and email me the results of the error. In PHP5, they added one more additional error type, and I needed to handle this:

In PHP4, I create a error type array:

$type = array(
1   =>  "Error",
2   =>  "Warning",
4   =>  "Parsing Error",
8   =>  "Notice",
16  =>  "Core Error",
32  =>  "Core Warning",
64  =>  "Compile Error",
128 =>  "Compile Warning",
256 =>  "User Error",
512 =>  "User Warning",
1024=>  "User Notice");

With PHP5, they added the 'STRICT' error type, and now I need to include that, or I'll get NOTICEs indicating that it's missing in the logs.

$type = array(
1   =>  "Error",
2   =>  "Warning",
4   =>  "Parsing Error",
8   =>  "Notice",
16  =>  "Core Error",
32  =>  "Core Warning",
64  =>  "Compile Error",
128 =>  "Compile Warning",
256 =>  "User Error",
512 =>  "User Warning",
1024=>  "User Notice",
2048=> "Strict");

comments - I also noticed that I was doing a bad habit of commenting echo statements like this on occassion:

<?=//$val?>

This will give a syntax error in PHP5, and should be like this:

<?//$val?>

XML - As I mentioned above, I did a lot of work with XML web service stuff, and they completely overhauled XML handling.. which is fantastic, but a pain, since I had to update lots of code. Basically, domxml_open_mem() does not exist any more, and they went with simplexml_load_string(). simplexml_load_string() is absolutely awesome, but you need to change your code and add simplexml to your USE flag. If you need examples of converting your code, let me know and I'll post some examples.

Keeping a close eye on the error logs is vital to ensure that your conversion of PHP4 to PHP5 was a smooth and successful cutover. Hope this helps, and if you have any questions, please feel free to comment.