If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

Upgrading PHP FAQ

What is this forum for?
You or your host have upgraded PHP and, despite your best efforts, the site has broken, and you can't find what the problem is. Or maybe you're thinking of upgrading, and want some idea of places where the site might break if you do.

A bit of history, and where to find out what happened.
PHP's developers have tried very hard over the years to maintain backward-compatibility, so that scripts written for older versions of PHP will continue to run in newer ones, but they can never be 100% successful. They give advance warning of changes that can break older scripts, and the bigger the change in versions the bigger the version number change. A list of backward-incompatible and other significant changes are chronicled in the history section of the manual.

PHP 5
The transition from PHP4 to PHP5 was very big: not just in the way objects were passed to functions was completely overhauled to match the way other languages did it, but when PHP 5.0.0 was released in 2004 development of PHP 4 basically stopped. See migration5 for an almost full list.

The transition from 5.0 to 5.1 shook out a lot of the bugs found during use of 5.0, and introduced a number of features that had been put on hold. Backwards compatibility was maintained. An overhaul to date/time handling was introduced, and PDO (the recommended database interaction interface: mysql_query() is just so last century) was enabled by default. migration51

Version 5.2 made a few changes that were not compatible with 5.1 and a few more rough edges were smoothed out (like having __toString() work as expected instead of only in a couple of special situations). Mostly, however, it was devoted to additional functionality. migration52.

Migrating from 5.2 to 5.3 (migration53) gives you additional significant features like closures and namespaces (mmm ... closures ...), at the expense of a few backward incompatibilities (e.g., namespace is now a reserved word).

Migrating to 5.4 (which, not surprisingly, is outlined in migration54) is a similar jump. It removes a lot of stuff that should have already been removed from any software that is being maintained - things like magic_quotes and safe_mode - are gone. It has also adds a number of refinements to the syntax, and things called traits to ease code reuse across class hierarchies without requiring inheritance.

Speaking of things that are gone, the MySQL extension is now deprecated and notice has been given that the mysql_* functions will be removed in the future; they should not be used in any new software and existing software that uses them should be getting modified now if you don't want to be left stranded .

The principal incompatibility between 5.5 migration55 and earlier versions is that support has been dropped for Windows XP and 2003. Most of the changes are syntactic enhancements (most significantly, foreach($list_of_pairs as list($a, $b)), try/catch blocks can now have a finally). Internationalisation (intl) has been given an overhaul, coinciding with the upgrade to ICU version 4. Password hashing has been given a new API. There is a new class of object called Generators, that introduces the yield keyword some of you may recognise from languages such as C#, Python, and JavaScript 1.7.

Migrating from 5.5 to 5.6 is simpler (migration56); there are only a few things that might break, but mostly only in somewhat esoteric situations. A few more things have been deprecated (most notably for most users, the use of $HTTP_RAW_POST_DATA). Of greater interest is what has been added: syntax for exponentiation, and a cleaner way of specifying variadic functions (instead of a lot of fiddling around with func_get_args); namespaces can use functions and constants from other namespaces as well as classes; constants can now be (constant) expressions instead of merely literals; and there is now an inbuilt debugger as well as server.

PHP 6
There is NO PHP6.

When PHP5 was released, development of PHP6 began. The process was publicised and a fair bit was written about the subject, but while development builds appeared the PHP6 project was eventually discarded in favour of cleaning up the language in the PHP5 branch. To avoid confusion with the stillborn PHP6, the release version went straight to PHP7. The decision and a link to the discussion behind it is on https://wiki.php.net/rfc/php6

PHP 7migration70
As befitting a major version, there are a lot of changes. Backward compatibility with PHP5 is still important, but there are more than the usual incompatibilities. A lot of them are to do with cleaning up how the language works, so most of them will only bite people who were writing hairy code to begin with (like $foo->$bar['baz']() ).

For some people, the most significant change is that many fatal errors have been turned into exceptions: if you have a custom error handler you'll want to check how it behaves; the error will become an "uncaught exception" instead of whatever it was (because pre-PHP7 code won't have a catch block for the new Error exception class).

Division by zero now works according to standard floating-point conventions (1/0=INF, -1/0=-INF, 0/0=NAN) but will still trigger a warning. The % operator will throw a DivisionByZero exception if a zero modulus is used.

Now for some good news. Lots of neat stuff. Generator delegation, anonymous classes, more flexible assertion handling, integer division, array constants, a ?? operator that works the way a lot of people thought ?: should, a type-juggling comparison operator <=>, scalar (as well as object) type hinting for both function arguments and return values...

Internally, it's a lot less demanding on host infrastructure: it's faster (the claim is twice as fast), mainly due to much less memory use. Oh, and it's 64-bit on 64-bit machines: PHP_INT_MAX=9,223,372,036,854,775,807.

Version 7.1: One of the problems with type hinting as introduced from PHP 5.0 through to 7.0 is that if you specified a type for an argument or return value, you couldn't pass or return NULL. Well, now you can. Also, the list($a) construct can be abbreviated to [$a] just as array could from 5.4. You can also have associative list statements. You can control the visibility of class constants, and have a single catch for multiple exception types.
Some things got stricter: not passing enough arguments to a function is now an Error instead of a warning, and some functions are forbidden from being called dynamically. Session key generation was streamlined, resulting in some of its associated .ini directives becoming irrelevant. SSLv2 has been dropped from OpenSSL, and mcrypt was deprecated.

Version 7.2: Speaking of mcrypt, that's now gone; its replacement is either OpenSSL or the new Sodium library. Keep going with the former if you're already using and are happy with it, but if you're starting from scratch it won't hurt to look at the latter.
Sodium is the big new thing in this version. Casting arrays to objects or objects to arrays won't cause elements/properties with numeric keys/field names to go wonky. Counting strings and scalar values will trigger a warning (because you know the answer is always going to be 1); for acceptable counting, the thing being counted has to be either an array or an object implementing Countable.
Using bare unquoted words as strings will now trigger a Warning instead of a mere Notice. PHP 8 will make it an Error. __autoload() create_function(), each(), track_errors, and casting to "(unset)" are among the things that have been deprecated in advance of their removal in PHP 8.

If PHP is supposed to be so backward compatible, why has my site suddenly stopped working?
Before ripping into your code or throwing it out, check your configuration: almost certainly there will be differences in the php.ini file that your old installation had and the new one. If you still have the old habit (pre-XML days) habit of writing "<?" instead of "<?php" you'll want to know that php.ini-recommended has short_open_tag turned off. Similarly, if you're still in the bad habit of using plain variables for submitted form fields and session data, instead of the $_POST, $_GET, $_REQUEST, and $_SESSION arrays that were introduced in PHP4.1, the default setting of register_globals in both php.ini-recommended and php.ini-dist is off. In both cases you could just turn them on if you needed to, but if you don't take the opportunity to upgrade your code you'll be left even further behind (if you continue to insist on having register_globals turned on you will not be able to use PHP5.4).
So: check all the obvious things. Is it plugged in? Is it turned on? Is it installed? Compare your old php.ini with the new one. (Windows users: are all the extension .dll's enabled that should be enabled?) For each difference you find (like I say, you'll almost certainly find some), find out why they are different and how changing that setting affects PHP's behaviour. There are two places to find out information about each .ini setting: the list of ini settings is one starting point, and the other is the documentation contained in the php.ini file itself. After checking php.ini, remember that many of the settings can be further modified by .htaccess files and the like: if you upgraded your webserver at the same time (which is not uncommon), you will want to walk yourself through any configuration changes there too.

"Warning: Unknown: Your script possibly relies on a session side-effect which existed until PHP 4.2.3. Please be advised that the session extension does not consider global variables as a source of data, unless register_globals is enabled. You can disable this functionality and this warning by setting session.bug_compat_42 or session.bug_compat_warn to off, respectively" Whaarrrgarbblll?!
Best Practice to avoid this error message:

Upgrade to PHP7.

Second Best Practice:

Upgrade to PHP5.6.

Bottom preference if upgrading is infeasible in the short term:

Turn the php.ini setting "session.bug_compat_42" off.

Don't use session_register() and session_unregister() to work with session variables any more. Use the $_SESSION array.

Which previous version? What problems are you having? The PHP manual has a section migration70 that describes what has changed in PHP that will help you work out if anything in your code needs to change.