Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

506 lines (373 sloc) 16.272 kb
1. Backward Incompatible Changes
2. New Features
3. Changes in SAPI modules
4. Deprecated Functionality
5. Changed Functions
6. New Functions
7. New Classes and Interfaces
8. Removed Extensions and SAPIs
9. Other Changes to Extensions
10. New Global Constants
11. Changes to INI File Handling
12. Windows Support
13. Other Changes
1. Backward Incompatible Changes
Language changes
Changes to variable handling
* Indirect variable, property and method references are now interpreted with
left-to-right semantics. Some examples:
$$foo['bar']['baz'] // interpreted as ($$foo)['bar']['baz']
$foo->$bar['baz'] // interpreted as ($foo->$bar)['baz']
$foo->$bar['baz']() // interpreted as ($foo->$bar)['baz']()
Foo::$bar['baz']() // interpreted as (Foo::$bar)['baz']()
To restore the previous behavior add explicit curly braces:
* The global keyword now only accepts simple variables. Instead of
global $$foo->bar;
it is now required to write the following:
global ${$foo->bar};
* Parentheses around variables or function calls no longer have any influence
on behavior. For example the following code, where the result of a function
call is passed to a by-reference function
function getArray() { return [1, 2, 3]; }
$last = array_pop(getArray());
// Strict Standards: Only variables should be passed by reference
$last = array_pop((getArray()));
// Strict Standards: Only variables should be passed by reference
will now throw a strict standards error irregardless of whether parentheses
are used. Previously no notice was generated in the second case.
* Array elements or object properties that are automatically created during
by-reference assignments will now result in a different order. For example
$array = [];
$array["a"] =& $array["b"];
$array["b"] = 1;
now results in the array ["a" => 1, "b" => 1], while previously the result
was ["b" => 1, "a" => 1];
Relevant RFCs:
Changes to list()
* list() will no longer assign variables in reverse order. For example
list($array[], $array[], $array[]) = [1, 2, 3];
will now result in $array == [1, 2, 3] rather than [3, 2, 1]. Note that only
the **order** of the assignments changed, but the assigned values stay the
same. E.g. a normal usage like
list($a, $b, $c) = [1, 2, 3];
// $a = 1; $b = 2; $c = 3;
will retain its current behavior.
* Empty list() assignments are no longer allowed. As such all of the following
are invalid:
list() = $a;
list(,,) = $a;
list($x, list(), $y) = $a;
* list() no longer supports unpacking strings (while previously this was only
supported in some cases). The code
$string = "xy";
list($x, $y) = $string;
will now result in $x == null and $y == null (without notices) instead of
$x == "x" and $y == "y". Furthermore list() is now always guaranteed to
work with objects implementing ArrayAccess, e.g.
list($a, $b) = (object) new ArrayObject([0, 1]);
will now result in $a == 0 and $b == 1. Previously both $a and $b were null.
Relevant RFCs:
Changes to foreach
* Iteration with foreach() no longer has any effect on the internal array
pointer, which can be accessed through the current()/next()/etc family of
functions. For example
$array = [0, 1, 2];
foreach ($array as &$val) {
will now print the value int(0) three times. Previously the output was int(1),
int(2) and bool(false).
* When iterating arrays by-value, foreach will now always operate on a copy of
the array, as such changes to the array during iteration will not influence
iteration behavior. For example
$array = [0, 1, 2];
$ref =& $array; // Necessary to trigger the old behavior
foreach ($array as $val) {
will now print all three elements (0 1 2), while previously the second element
1 was skipped (0 2).
* When iterating arrays by-reference, modifications to the array will continue
to influence the iteration. However PHP will now do a better job of
maintaining a correct position in a number of cases. E.g. appending to an
array during by-reference iteration
$array = [0];
foreach ($array as &$val) {
$array[1] = 1;
will now iterate over the appended element as well. As such the output of this
example will now be "int(0) int(1)", while previously it was only "int(0)".
* Iteration of plain (non-Traversable) objects by-value or by-reference will
behave like by-reference iteration of arrays. This matches the previous
behavior apart from the more accurate position management mentioned in the
previous point.
* Iteration of Traversable objects remains unchanged.
Relevant RFC:
Changes to parameter handling
* It is no longer possible to define two function parameters with the same name.
For example, the following method will trigger a compile-time error:
public function foo($a, $b, $unused, $unused) {
// ...
Code like this should be changed to use distinct parameter names, for example:
public function foo($a, $b, $unused1, $unused2) {
// ...
* The func_get_arg() and func_get_args() functions will no longer return the
original value that was passed to a parameter and will instead provide the
current value (which might have been modified). For example
function foo($x) {
will now print "2" instead of "1". This code should be changed to either
perform modifications only after calling func_get_arg(s)
function foo($x) {
or avoid modifying the parameters altogether:
function foo($x) {
$newX = $x + 1;
* Similarly exception backtraces will no longer display the original value that
was passed to a function and show the modified value instead. For example
function foo($x) {
$x = 42;
throw new Exception;
will now result in the stack trace
Stack trace:
#0 file.php(4): foo(42)
#1 {main}
while previously it was:
Stack trace:
#0 file.php(4): foo('string')
#1 {main}
While this should not impact runtime behavior of your code, it is worthwhile
to be aware of this difference for debugging purposes.
The same limitation also applies to debug_backtrace() and other functions
inspecting function arguments.
Relevant RFC:
Changes to integer handling
* Invalid octal literals (containing digits larger than 7) now produce compile
errors. For example, the following is no longer valid:
$i = 0781; // 8 is not a valid octal digit!
Previously the invalid digits (and any following valid digits) were simply
ignored. As such $i previously held the value 7, because the last two digits
were silently discarded.
* Bitwise shifts by negative numbers will now throw a warning and return false:
var_dump(1 >> -1); // bool(false)
// Warning: Bit shift by negative number
* Left bitwise shifts by a number of bits beyond the bit width of an integer
will always result in 0:
var_dump(1 << 64); // int(0)
Previously the behavior of this code was dependent on the used CPU
architecture. For example on x86 (including x86-64) the result was int(1),
because the shift operand was wrapped.
* Similarly right bitwise shifts by a number of bits beyond the bit width of an
integer will always result in 0 or -1 (depending on sign):
var_dump(1 >> 64); // int(0)
var_dump(-1 >> 64); // int(-1)
Relevant RFC:
Changes to string handling
* Strings that contain hexadecimal numbers are no longer considered to be
numeric and don't receive special treatment anymore. Some examples of the
new behavior:
var_dump("0x123" == "291"); // bool(false) (previously true)
var_dump(is_numeric("0x123")); // bool(false) (previously true)
var_dump("0xe" + "0x1"); // int(0) (previously 16)
var_dump(substr("foo", "0x1")); // string(3) "foo" (previously "oo")
// Notice: A non well formed numeric value encountered
filter_var() can be used to check if a string contains a hexadecimal number
or convert such a string into an integer:
$str = "0xffff";
if (false === $int) {
throw new Exception("Invalid integer!");
var_dump($num); // int(65535)
* Due to the addition of the Unicode Codepoint Escape Syntax for double-quoted
strings and heredocs, "\u{" followed by an invalid sequence will now result in
an error:
$str = "\u{xyz}"; // Fatal error: Invalid UTF-8 codepoint escape sequence
To avoid this the leading backslash should be escaped:
$str = "\\u{xyz}"; // Works fine
However, "\u" without a following { is unaffected. As such the following code
won't error and will work the same as before:
$str = "\u202e"; // Works fine
Relevant RFCs:
Other language changes
. Removed ASP (<%) and script (<script language=php>) tags.
. Removed support for assigning the result of new by reference.
. Removed support for scoped calls to non-static methods from an incompatible
$this context. See details in
. Removed support for #-style comments in ini files. Use ;-style comments
. $HTTP_RAW_POST_DATA is no longer available. Use the php://input stream instead.
Standard library changes
. call_user_method() and call_user_method_array() no longer exists.
. ob_start() no longer issues an E_ERROR, but instead an E_RECOVERABLE_ERROR in case an
output buffer is created in an output buffer handler.
. Added hybrid sorting algo zend_sort for better performance.
. Added stable sorting algo zend_insert_sort.
. Removed dl() function on fpm-fcgi.
- Date:
. Removed $is_dst parameter from mktime() and gmmktime().
. dba_delete() now returns false if the key was not found for the inifile
handler, too.
. Requires libgmp version 4.2 or newer now.
. gmp_setbit() and gmp_clrbit() now return FALSE for negative indices, making
them consistent with other GMP functions.
- Session
. session_start() accepts all INI settings as array. e.g. ['cache_limiter'=>'private']
sets session.cache_limiter=private. It also supports 'read_and_close' which closes
session data immediately after read data.
. Save handler accepts validate_sid(), update_timestamp() which validates session
ID existence, updates timestamp of session data. Compatibility of old user defined
save handler is retained.
. SessionUpdateTimestampHandlerInterface is added. validateSid(), updateTimestamp()
is defined in the interface.
. session.lazy_write(default=On) INI setting enables only write session data when
session data is updated.
. Removed support for /e (PREG_REPLACE_EVAL) modifier. Use
preg_reaplace_callback() instead.
- Standard:
. Removed string category support in setlocale(). Use the LC_* constants
. Removed set_magic_quotes_runtime() and its alias magic_quotes_runtime().
. Rejected RFC 7159 incompatible number formats in json_decode string -
top level (07, 0xff, .1, -.1) and all levels ([1.], [1.e1])
. Empty PHP string passed to json_encode emits a JSON syntax error.
- Stream:
. Removed set_socket_blocking() in favor of its alias stream_set_blocking().
2. New Features
- Core
. Added null coalesce operator (??).
. Support for strings with length >= 2^31 bytes in 64 bit builds.
. Closure::call() method added.
. Added \u{xxxxxx} Unicode Codepoint Escape Syntax for double-quoted strings
and heredocs.
. define() now supports arrays as constant values, fixing an oversight where define() did not support arrays yet const syntax did.
. Added the comparison operator (<=>), aka the spaceship operator.
3. Changes in SAPI modules
. Fixed bug #65933 (Cannot specify config lines longer than 1024 bytes).
. Listen = port now listen on all addresses (IPv6 and IPv4-mapped).
4. Deprecated Functionality
5. Changed Functions
- parse_ini_file():
- parse_ini_string():
. Added scanner mode INI_SCANNER_TYPED to yield typed .ini values.
- unserialize():
. Added second parameter for unserialize function
(RFC: allowing to specify
acceptable classes:
unserialize($foo, ["allowed_classes" => ["MyClass", "MyClass2"]);
6. New Functions
. Added gmp_random_seed().
- Standard
. Added intdiv() function for integer division.
7. New Classes and Interfaces
8. Removed Extensions and SAPIs
- sapi/aolserver
- sapi/apache
- sapi/apache_hooks
- sapi/apache2filter
- sapi/caudium
- sapi/continuity
- sapi/isapi
- sapi/milter
- sapi/phttpd
- sapi/pi3web
- sapi/roxen
- sapi/thttpd
- sapi/tux
- sapi/webjames
- ext/mssql
- ext/sybase_ct
For more details see
9. Other Changes to Extensions
10. New Global Constants
- Core
. PHP_INT_MIN added.
11. Changes to INI File Handling
- Core
. Removed asp_tags ini directive. Trying to enable it will result in a fatal
. Removed always_populate_raw_post_data ini directive.
12. Windows Support
- Core
. Support for native 64 bit integers in 64 bit builds.
. Support for large files in 64 bit builds.
13. Other Changes
- Core
. Instead of being undefined and platform-dependent, NaN and Infinity will
always be zero when casted to integer.
. Calling a method on a non-object no longer raises a fatal error; see
. Error messages for zend_parse_parameters, type hints and conversions now always say "integer" and "float" instead of "long" and "double".
Jump to Line
Something went wrong with that request. Please try again.