Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
<?php
/**
* @see https://raw.githubusercontent.com/php/php-src/php-7.0.0beta2/UPGRADING
*/
/**
* 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']()
/**
* The global keyword now only accepts simple variables. Instead of
*/
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
/**
* Array elements or object properties that are automatically created during
* by-reference assignments will now result in a different order.
*/
$array = [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
/**
* list() will no longer assign variables in reverse order.
*/
list($array[], $array[], $array[]) = [1, 2, 3];
var_dump($array);
/**
* 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;
/**
* 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.
*/
$array = [0, 1, 2];
foreach ($array as &$val) {
var_dump(current($array));
}
/**
* 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.
*/
$array = [0, 1, 2];
$ref =& $array; // Necessary to trigger the old behavior
foreach ($array as $val) {
var_dump($val);
unset($array[1]);
}
/**
* 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) {
var_dump($val);
$array[1] = 1;
}
/**
* 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:
*/
class A
{
public function foo($a, $b, $unused, $unused) {
// ...
}
}
/**
* 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).
*/
function foo($x) {
$x++;
var_dump(func_get_arg(0));
}
foo(1);
/**
* Similarly exception backtraces will no longer display the original value that
* was passed to a function and show the modified value instead.
*/
function foo($x) {
$x = 42;
throw new Exception;
}
foo("string");
/**
* 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!
/**
* Bitwise shifts by negative numbers will now throw an ArithmeticError:
*/
var_dump(1 >> -1);
// ArithmeticError: 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)
/**
* 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)
/**
* 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";
$int = filter_var($str, FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX);
if (false === $int) {
throw new Exception("Invalid integer!");
}
var_dump($int); // 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
/**
* Removed support for static calls to non-static calls form an incompatible
* $this context. In this case $this will not be defined, but the call will be
* allowed with a deprecation notice. An example:
*/
class A {
public function test() { var_dump($this); }
}
// Note: Does NOT extend A
class B {
public function callNonStaticMethodOfA() { A::test(); }
}
(new B)->callNonStaticMethodOfA();
/**
* The yield language construct no longer requires parentheses when used in an
* expression context. It is now a right-associative operator with precedence
* between the "print" and "=>" operators. This can result in different behavior
* in some cases, for example:
*/
echo yield -1;
yield $foo or die;
// Was previously interpreted as
yield ($foo or die);
// And is now interpreted as
(yield $foo) or die;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment