kvz.io
Published on

Prepare for PHP 5.3

Authors
  • avatar
    Name
    Kevin van Zonneveld
    Twitter
    @kvz

PHP 5.3 is a big leap forward for PHP and brings of a lot of neat features. However, big leaps can also mean big changes and potentially big breakage when it comes to backwards compatibility.

I did some experimenting with running a big legacy application and a CakePHP application on PHP 5.3 and would like to share my findings with you. Here are a couple of tips to prepare your code for PHP 5.3

Installing PHP 5.3 on Ubuntu Jaunty

First off, by reading this article you may want to testdrive PHP 5.3 yourself.

If you haven't tried PHP 5.3 yet and you want to give it a go right now, but you don't want to mess up any Production or even Development environment, Virtualization can help you with that.

Just

  • Launch a virtual Ubuntu Jaunty instance (desktop versions work too, and may be easier on you)
  • Use the dotdeb.org repositories to install PHP 5.3 (thanks to sysadmin guru Martijn Kint for that great find)
  • Point Apache's (or nginx or whatever) document root to your workstation's shared code directory.

Et voila. An independent test platform that's able to reflect your code changes in real time.

Now on to my findings.

Short Tags

When you do a fresh PHP 5.3 install on an Ubuntu Jaunty server, short tags, also known as: <?

New releases can have support off by default, hence just showing code as plaintext. Including db passwords.

This is the stuff that can get you fired.

So if you have these short tags, lets get rid of them. But how, there are so many!

Update #1 - As noted by Rune Kaagaard and Philip Olson in the comments, support for short tags is still a subject of discussion. Whether it will be turned off by default or supported in PHP 6 also depends on the package maintainers of each distribution (looks like Ubuntu is going for the strict approach).

Regex to the Rescue?

If you have a lot of short tags, the following regexes could help to convert them:

replace: '<\?='
   with: '<\?php echo '

replace: '<\?(?!php|xml)'
   with: '<\?php'

The order of these replace actions is important.

Now, be sure to go over the changes manually with a tool like regexxer though. Cause if you're not careful code generators, highlighters & XML tools will break. Consider the following real life example:

<?php
$CodeRow->replace('<?', '<?php', 'T_OPEN_TAG');
?>

By our replace action, this would now read:

<?php
$CodeRow->replace('<?php', '<?php', 'T_OPEN_TAG');
?>

Making that line completely useless and introducing a bug. So please, really go over the changes manually. Regexxer will make that job less painful already.

Update #2: As Bernhard mentions in the comments, there is a much better way of removing shorttags from your PHP code.

After the Changes

Test your code thoroughly before you commit.

PHP Deprecated Warnings

Some 'old' syntax still works but generates "Deprecated" warnings. These are telling you to change your code before it's too late: future versions of PHP will no longer support it. At all.

The following example is still used in quite some code, but as of PHP 5.3 will generate "Deprecated" warnings.

<?php
$log = & new Logger('file', '/var/log/app.log');
?>

They want you to get rid of the '&'.

Obviously - if you are the author of such lines - you should change your code. Now is the time.

But let's say you also use a framework (CakePHP in my case), and you are not the author. You need to wait for others to fix it (don't worry, PHP 5.3 releases of Cake are in the works, just not stable yet). But if you still want to run PHP 5.3 right now with a deprecated framework codebase you can't change: you can turn off these warnings by changing the level of error reporting.

Here's an example that still let's you see other debug messages like Notices (which is great during development), but just turns off the Deprecated warnings (which are useless if they concern the framework's code):

<?php
error_reporting(E_ALL & ~ E_DEPRECATED);
?>

.. basically saying: Show all warnings except deprecated.

So put this wherever you currently set the error_reporting level.

For CakePHP 1.2, I found I had to hack my core in /cake/libs/configure.php at line #291 to get rid of the deprecated warnings.

MySQL

In Ubuntu (thanks Philip Olson), PHP 5.3 uses a native MySQL driver (mysqlnd) and it enforces strong passwords. We still had some legacy 16bit MySQL passwords and so MySQL guru Erwin Bleeker upgraded them in order for mysql_connect to work. Good thing I suppose ; )

Extensions

I had some extensions like php5-xdebug, php5-xcache, php5-memcache that I previously installed with APT package management, but now gave version conflicts with my custom dotdeb.org packages.

Well, just uninstall them with apt (or rpm, or whatever) and reinstall them with pecl like this:

$ pecl install -f memcache

So that the extensions are rebuild for your current PHP version and the conflicts are resolved. Make sure your php.ini files point to the right .so files though.

User Contributions

In the comments there are developers who ran into other issues as well. Summarizing:

  • Many array functions that used to allow passing objects no longer do - Matthew Weier O'Phinney
  • Convert ereg_ functions to preg_ ones
  • magic_quotes_gpc and register_globals are gone - Giorgio Sironi

Alright

OK so after those changes, all of my old code ran fine on PHP 5.3 and it was time to really go & enjoy the new features like namespaces, closures, increased performance & late static binding! Awesome..

I'm curious. What problems did you encounter trying to run old code on PHP 5.3? Were you able to fix it? Please share your experience.

Legacy Comments (18)

These comments were imported from the previous blog system (Disqus).

Andrea Giammarchi
Andrea Giammarchi·

I wonder how can you suggest to remove short tags, deprecated, and suggest error_reporting modification to avoid deprecated code. PHP 5.3 is here since ages, it is about the time to gradually upgrade codes removing silly, useless, redundant parts. deprecated should be enabled, imho, as every other error level.

Kev van Zonneveld
Kev van Zonneveld·

@ Andrea Giammarchi: Hi Andrea thanks for your comment.

I totally agree, if you read more carefully you will find that I encourage people to change their code.

But in the case that they run other people\'s code (Like a CakePHP 1.2 Core) chances are you will be running 5.3 to test your own code before you get a chance to upgrade your Cake Core (1.3, 2, or even 3 aren\'t stable yet). So in such cases you may want to turn of deprecated warnings for the framework until you can upgrade to a new release.

Andrea Giammarchi
Andrea Giammarchi·

Kevin, in my opinion IT means updates. If people are stuck in old Cake version, or whatever old framework it is, they can be stuck with old PHP version and slowly go down behind updated applications/developers. We all complain about IE6 and I do not know how many of \"us\" are still in .NET version 1/2, PHP 4, etc etc ... update your knowledge/skills, this is the only way to survive in IT. Just my 2 cents, good post though in any case.

Matthew Weier O\'Phinney
Matthew Weier O\'Phinney·

We just completed PHP 5.3 compatibility support for Zend Framework, and ran into many similar issues to what you reported. In addition, there are a variety of signatures that changed, and many array functions that used to allow passing objects no longer do.

That said, it\'s not a terribly difficult undertaking. You just have to keep in mind the benefits (ability to continue upgrading your PHP version to latest stable; faster execution; better object model; etc), as it can be a pretty boring task, particularly if you have to run a large test suite over and over again. :)

@ Andrea Giammarchi: I don\'t understand your comment, \"PHP 5.3 is here since ages\" -- last I checked, the official release was just a month ago. While it\'s been on the horizon for a good six months, that\'s not the same as saying there\'s been a stable base against which to test development. It will be some time before there is widespread PHP 5.3 adoption.

Rune Kaagaard
Rune Kaagaard·

Last I researched on shorttags the vote was that they they should be kept. See: http://www.php.net/~derick/...

what are your source for this claim?
Cheers

Andrea Giammarchi
Andrea Giammarchi·

@Matt, I mean these changes are well known since ages and most of them where already possible. I personally use PHP 5.3 since \"ages\" (first alpha) specially to test old code and start to migrate it. This is what I was talking about.

@Rune, vote or not vote, short tag is a mess for modules and a bit arrogant from development point of view. XML starts with <?xml, clear enough, other languages specify who they are ... in 10 years I have never used short tags since I always thought they could have cause mess, indeed you have to be carefull with XML declaration ... is it a good way to code? I do not think so. Same is for ASP tag emulator, so you cannot put both languages in the same page ... good? BAD!

Philip Olson
Philip Olson·

While I agree that people should not use short_open_tag, I want to clarify that:

-- They are not disabled by default in PHP 5.3. The two distributed php.ini-* files do disable them, but the default is still On. Although, of course a package maintainer might choose to enable a certain php.ini file within a package, like the one mentioned here for Ubuntu.

-- They may or may not be removed from PHP 6, a decision that may or may not depend on a decision to decouple <?= from short_open_tag. My opinion is there will be a decoupling.

Also, mysqlnd is not enabled by default although it appears the Ubuntu package maintainer here did (which is a good thing).

See Also: http://php.net/migration53

Cory Kaufman
Cory Kaufman·

I wish PHP failed more loudly when short tags are disabled. I\'ve had them turned off on my local server for a while, but it always leads to some odd results when I download code that uses short tags.

Giorgio Sironi
Giorgio Sironi·

I was using ereg_*() functions and I have to convert to preg_*() ones. Fortunetale magic_quotes_gpc and register_globals are gone from a long time.
@Matthew: when Zend_Loader will support namespaced classes?

Kev van Zonneveld
Kev van Zonneveld·

@ Andrea Giammarchi: No sorry I still think you\'re missing my point. As we speak, CakePHP people are working on PHP 5.3 versions. I just want to enable people to testdrive their code right now even though they don\'t have a stable 5.3 framework core - yet.
So comparison with IE6 isn\'t really working as I\'m encouraging people to update everything. Please read my article more carefully, I have the feeling your IE6 concerns where triggered by false alarm.

@ Matthew Weier O\'Phinney: That\'s a nice summary of of PHP 5.3 goodness. I\'m actually the most excited about this release since... Well a very long time : )

@ Rune Kaagaard: Thanks. I read it somewhere, but apparently the jury is still out on that one, let me adjust the article

@ Philip Olson: Thanks you for clarifying on that subject, I will adjust the article accordingly

@ Cory Kaufman: I agree that would be nice, but I imagine a fix for that would be really hacky. I mean: it either recognizes shorttags or it doesn\'t. A state inbetween that detects but does not act on it may introduce bugs on it\'s own.

@ Giorgio Sironi: Thanks I will add them as well!

xrado
xrado·

i really don\'t see a reason for dropping short tag support. writing php a 1000 times is a nonsense

Kev van Zonneveld
Kev van Zonneveld·

@ xrado: Well with any modern IDE you shouldn\'t have to type that manually.

They probably should have never supported it in the first place. PHP isn\'t the only language out there. Just think of XML:

[CODE=\"XML\"]
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
[/CODE]

This can cause confusion, so I understand why they want to drop it.

Rune Kaagaard
Rune Kaagaard·

@Philip Olson, Thx for clarifying. Interesting to hear about the possible decoupling of the <?=$some_var?> syntax.

@Andrea Giammarchi, how is short tag a mess for modules? (and what kind of modules are you referring to?). I have always felt that having the ease of the <?=$some_var?> syntax _by far_ made the impurity of having to echo \"<?xml\" ... worth it. PHP is a super cool template language where shorttags fits in nicely. so shortags....? GOOD! :)

Nate Abele
Nate Abele·

Hey Kevin, good post. I just wanted to let you know that 5.3 support has now been pushed to the CakePHP 1.3 branch, which will be released shortly, so core code changes shouldn\'t be be required soon.

Kev van Zonneveld
Kev van Zonneveld·

@ Nate Abele: Thanks for the heads-up. I saw on twitter that the dev version of 1.3 was released today. Nice job! Were you able to get your hands on some Club Mate for that ? ; )

V
V·

You are right about the short tags, but not completely. Check out the stream wrappers php provides. Short tags can be used within streams, even if they are disabled. This is a good way to allow them in views only. Disabling them by default is a goog call IMO.

Bernhard H.
Bernhard H.·

I recently wanted to get rid of the short tags. There was really much code and I didn\'t write too much of it, so I couldn\'t rely on a regexp. I looked around and found this:
http://stackoverflow.com/qu...

Well, I put it into a script and called it like that:
[CODE=\"sh\"]
find project/dir/ -type f -iname \"*.php\" -exec php -d short_open_tag=On the_script.php {} \\;
[/CODE]
and the_script.php would contain:
[CODE=\"php\"]
<?php

$file=$argv[1];
echo \"Replacing short open tags in \\\"$file\\\"...\";

$content = file_get_contents($file);
$tokens = token_get_all($content);
$output = \'\';

foreach($tokens as $token) {
if(is_array($token)) {
list($index, $code, $line) = $token;
switch($index) {
case T_OPEN_TAG_WITH_ECHO:
$output .= \'<?php echo \';
break;
case T_OPEN_TAG:
$output .= \'<?php \';
break;
default:
$output .= $code;
break;
}

}
else {
$output .= $token;
}
}
[/CODE]

As you can see it\'s using tokenizer parser, so it could save you some headache. (Unless you have *.php files that can not be parsed etc.)
The only problem was that it stripped some newlines even after long tags, so the svn diff got really huge. I think i can live with this though.

Another problem I faced switching to PHP5.3 was rather odd:
I had a php class named SplQueue that was autoloaded if SPL didn\'t already provide it, which was always the case - until PHP5.3. It used the same methods and I planed that it would silently be replaced by the SPL one but:
Suddenly there where exceptions all over the place because SplQueue throws (undocumented) Exceptions when dequeue-ing from an empty queue. That\'s quite silly - but OK, I figured it would be easiest just not to use the SPL-Class. So be aware that the SPL docs are... erm... not so well-proven yet.

Kev van Zonneveld
Kev van Zonneveld·

@ Bernhard H.: That\'s very useful information Bernhard, thanks a lot for this!