#native_company# #native_desc#
#native_cta#

What’s new in PHP 5 and PHP 6

By Ian Gilfillan
on December 6, 2005

Most PHP installations out there are still running PHP 4.x. PHP 5.0 has been out a while, and PHP 5.1.1 has just been released. For those of you who haven’t yet upgraded, this month I look at some of the changes you can expect to find in the newer versions of PHP, as well as a preview of what you can look forward to in PHP 6.

Changes in PHP 5.0

As befits an entirely new version number, there are substantial differences between PHP 4 and PHP 5. Most of the hype was around the new object model, which was completely rewritten. The PHP 5 version is much more complete, and performs much better as well. In PHP 4, objects were really just primitive data types, and were referenced by value. In an attempt to retain as much backward compatibility as possible, setting the zend.ze1_compatibility_mode in PHP 5 allows compatibility with the version 4 methods. There are a number of other backward incompatible changes. These include:

  • New reserved keywords are mostly related to the object model (exception, final, php_user_filter, interface, implements, extends, public, private, protected, abstract, clone, try, catch, throw). Two words that were reserved in PHP 4 are no longer so (cfunction, old_function).
  • An object is no longer empty if it doesn’t have any properties.
  • The array_merge() function now only accepts arrays.
  • Classes may (depending on the usage) need to be declared before being used.
  • get_class(), get_parent_class() and get_class_methods() now return a case sensitive result. Previously results were lowercase.
  • strrpos() and strripos() now use the entire string as a needle. For example,

    var_dump(strrpos('ABCDEF','DAF'))

    returns

    int(3)
    

    in PHP 4
    and

    bool(false)
    

    in PHP 5.

  • If $_SERVER exists, it will be populated with argc and argv, which allows the CLI version to always have access to these.
  • ip2long() returns FALSE instead of -1 when passed an invalid IP address.
  • Functions defined in an included file can now be used at any time in the main file. PHP 5 will also issue a fatal error if the file is included twice (and therefore the functions are already defined), which would break some mangled legacy code I’ve seen where the same script was included 5 or 6 times.
  • The require_once() and include_once functions now take into account Windows case insensitivity, and would only include a file once even if the function is called multiple times with the filename being different cases.
  • Dispensing with the PHP 4 warnings, PHP 5 throws an error if it encounters illegal string offsets
  • The Tokenizer extension no longer define the unused T_ML_COMMENT constant.

Many of these incompatible changes are quite minor, and its likely you’ll have to do little, if anything to most of your scripts to get them ready for action on PHP 5. PHP 5 has better ways of doing many things, but if your aim is keeping things going, you shouldn’t have too many problems. Other changes in PHP 5 include:

  • Minor changes in the location of the command line CLI and CGI scripts, effectively elevating the newer CLI to the premier position.
  • A host of new functions, many to do with arrays, character conversion and streams.
  • The MySQL client libraries were not bundled with PHP 5 by default. Instead, the SQLite extension was included, which is basically a mini database engine, with the aim of removing the need for any setup and administration.
  • The mysqli (MySQL Improved extension) was added (though not included by default), to take advantage of the features in MySQL 4.1 and beyond. I’d been meaning to write a tutorial on this for a while, but as you’ll see when you get to the 5.1 changes, there’s no longer as much need.

For a full list of issues when changing from PHP 4 to PHP 5, see the official documentation on the PHP site.

Changes in PHP 5.1.x

At the time of writing, PHP 5.1.1 has just been released, a quick followup to the controversial 5.1.0. That version caused a mini-riot in the PHP mailing lists. In 5.1.0, certain key changes were hastily included in a late release candidate. Everything was quiet until the storm broke shortly after the final release. However, these changes were reversed in the 5.1.1 to prevent a pear::date conflict. 5.1.0 also ensured it won’t go down in the annals with any fond memories by including a couple of severe regressions that were quickly fixed in 5.1.1.

  • The lightning fast PDO is now part of the PHP core. Read more about it as it relates to other so-called abstraction layers in the article Database Abstraction in PHP, or in the official PDO documentation on the PHP site.
  • The PDO MySQL driver is now the preferred way to access MySQL – the older mysqli and mysql extensions are not enabled by default.
  • PHP 5.1 has some notable performance improvements over 5.0.
  • As mentioned above, Date/Time support was rewritten for 5.1.0, and then the changes reversed for 5.1.1. It’s likely that there will be further changes soon, albeit more carefully planned.
  • Abstract private methods were supported from PHP 5.0 to PHP 5.0.4. However, they are now disallowed.
  • It’s no longer permissible to redeclare a class constant. The following code will no longer work in 5.1, throwing an E_ERROR.
    <?php
    
    class anything {
        const const_name = 'value';
        const const_name = 'value2';
    }
    
    ?>
    
  • 14 older extensions have been removed from the PHP core. These include ext/cpdf, ext/dbx, ext/dio, ext/fam, ext/ingres_ii, ext/ircg, ext/mcve, ext/mnogosearch, ext/oracle, ext/ovrimos, ext/pfpro, ext/w32api, ext/yp, sapi/activescript. These are all still available in PECL, although not all are actively maintained.
  • There’s been a change in the way references are handled. It used to be possible to send, assign or return variables by reference that should have been returned by value. These include constants, functions that were themself returned by value, or results of an expression. Here’s an example:
    <?php
    $var1 = "value";
    
    function return_val() {
        global $var_name;
        return $var_name;
    }
    
    $var2 = &return_val();
    ?>
    

    This code used to work (until 5.0.4) but now throws an E_STRICT in 5.1.

5.1.x has got off to a rocky start, but there are some worthwhile improvements – the inclusion of PDO perhaps being the most far-reaching. See the changelog in the PHP documentation for the full list of PHP 5.1 (and earlier) changes.

Upcoming changes in PHP 6.0

PHP 6.0 looks to be an exciting release. Nothing is absolutely fixed yet, but it looks like it will see the demise of three of my pet peeves: register_globals, magic_quotes_gpc and safe_mode. The first was just a big security hole, the second messed with the data and made changing environments potentially nightmarish, while the third was a misnomer that nobody really understood, and provided a false sense of security. There’s also quite a lot of work scheduled to do with Unicode. Here are some of the changes:

  • The register_globals, safe_mode and the various magic quotes options will be removed.
  • The ereg extension is removed, while the XMLReader, XMLWriter and Fileinfo extensions are added to the core, and by default are on.
  • Another addition I find particularly exciting is that APC (Alternative PHP Cache) will be added to the core, though will be off by default. APC can provide serious performance benefits.
  • All E_STRICT messages will be merged into E_ALL, another positive change that will encourage good programming practice.
  • ASP style <% tags will no longer be supported.
  • Addition of a new 64-bit integers. The current integer type remains as is, 32 or 64-bit dependent on the platform.
  • Use of foreach with multi-dimensional arrays, for example foreach($array as $k => list($a, $b)).
  • A new switch in php.ini will allow you to disable Unicode semantics (by default they will be on).
  • There will also be various string improvements related to Unicode.
  • The microtime() function will return the full floating point number, rather than microseconds unix_timestamp, as at present, probably making the function more readily useful for most people.
  • The {} notation for string indexes will no longer be supported, while the [] version will get added substr() and array_slice() functionality. Previously [] was deprecated, but most developers, including myself, seem to use [].
  • FastCGI will always be enabled for the CGI SAPI, and will not be able to be disabled.
  • The ancient HTTP_*_VARS globals will no longer be supported. Everyone should have had more than enough time to remove any traces of these.
  • var will alias public. var was permitted with PHP4 classes, but in PHP 5 this raised a warning. In PHP 6 var will simply be an alias for public, so no warning is necessary.
  • The ze1 compatibility mode, which tried to retain PHP 4 behaviour but had some bugs, will be removed.
  • Dynamic functions will no longer be permitted to be called with static syntax.

There’s still much to be determined, namespaces being one of the more important, but as yet there’s little agreement. You can read the full minutes from the recent PHP Developer’s meeting here where PHP 6 was discussed at length. With PHP 6 still quite a way off, I’m sure there’ll be much more wailing and gnashing of teeth before we see the final product, but I’m excited by where it seems to be heading, and the progress that is being made.