Skip to content

Commit bfeae64

Browse files
committed
More extensive UPGRADING
I'd like UPGRADING to have a complete list of changes including code samples and suggested changes. Right now it's only a list of bullet points, where it is often required to read a linked RFC to understand the difference.
1 parent e10e151 commit bfeae64

File tree

1 file changed

+201
-23
lines changed

1 file changed

+201
-23
lines changed

UPGRADING

Lines changed: 201 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,32 +21,207 @@ PHP X.Y UPGRADE NOTES
2121
1. Backward Incompatible Changes
2222
========================================
2323

24-
- Core
25-
. list() now always supports ArrayAccess and never supports strings.
26-
Previously both were accepted in some situations and not in others.
27-
(RFC: https://wiki.php.net/rfc/fix_list_behavior_inconsistency)
28-
. Bitwise shifts by negative numbers of bits are disallowed (throws E_WARNING
29-
and gives FALSE, like a division by zero).
30-
. Left bitwise shifts by a number of bits beyond the bit width of an integer
31-
will always result in 0, even on CPUs which wrap around.
32-
. Right bitwise shifts by a number of bits beyond the bit width of an integer
33-
will always result in 0 or -1 (depending on sign), even on CPUs which wrap
34-
around.
24+
Core
25+
====
26+
27+
Changes to variable handling
28+
----------------------------
29+
30+
* Indirect variable, property and method references are now interpreted with
31+
left-to-right semantics. Some examples:
32+
33+
$$foo['bar']['baz'] // interpreted as ($$foo)['bar']['baz']
34+
$foo->$bar['baz'] // interpreted as ($foo->$bar)['baz']
35+
$foo->$bar['baz']() // interpreted as ($foo->$bar)['baz']()
36+
Foo::$bar['baz']() // interpreted as (Foo::$bar)['baz']()
37+
38+
To restore the previous behavior add explicit curly braces:
39+
40+
${$foo['bar']['baz']}
41+
$foo->{$bar['baz']}
42+
$foo->{$bar['baz']}()
43+
Foo::{$bar['baz']}()
44+
45+
* The global keyword now only accepts simple variables. Instead of
46+
47+
global $$foo->bar;
48+
49+
it is now required to write the following:
50+
51+
global ${$foo->bar};
52+
53+
* Parentheses around variables or function calls no longer have any influence
54+
on behavior. For example the following code, where the result of a function
55+
call is passed to a by-reference function
56+
57+
function getArray() { return [1, 2, 3]; }
58+
59+
$last = array_pop(getArray());
60+
// Strict Standards: Only variables should be passed by reference
61+
$last = array_pop((getArray()));
62+
// Strict Standards: Only variables should be passed by reference
63+
64+
will now throw a strict standards error irregardless of whether parentheses
65+
are used. Previously no notice was generated in the second case.
66+
67+
* Array elements or object properties that are automatically created during
68+
by-reference assignments will now result in a different order. For example
69+
70+
$array = [];
71+
$array["a"] =& $array["b"];
72+
$array["b"] = 1;
73+
var_dump($array);
74+
75+
now results in the array ["a" => 1, "b" => 1], while previously the result
76+
was ["b" => 1, "a" => 1];
77+
78+
Relevant RFCs:
79+
* https://wiki.php.net/rfc/uniform_variable_syntax
80+
* https://wiki.php.net/rfc/abstract_syntax_tree
81+
82+
Changes to list()
83+
-----------------
84+
85+
* list() will no longer assign variables in reverse order. For example
86+
87+
list($array[], $array[], $array[]) = [1, 2, 3];
88+
var_dump($array);
89+
90+
will now result in $array == [1, 2, 3] rather than [3, 2, 1]. Note that only
91+
the **order** of the assignments changed, but the assigned values stay the
92+
same. E.g. a normal usage like
93+
94+
list($a, $b, $c) = [1, 2, 3];
95+
// $a = 1; $b = 2; $c = 3;
96+
97+
will retain its current behavior.
98+
99+
* Empty list() assignments are no longer allowed. As such all of the following
100+
are invalid:
101+
102+
list() = $a;
103+
list(,,) = $a;
104+
list($x, list(), $y) = $a;
105+
106+
* list() no longer supports unpacking strings (while previously this was only
107+
supported in some cases). The code
108+
109+
$string = "xy";
110+
list($x, $y) = $string;
111+
112+
will now result in $x == null and $y == null (without notices) instead of
113+
$x == "x" and $y == "y". Furthermore list() is now always guaranteed to
114+
work with objects implementing ArrayAccess, e.g.
115+
116+
list($a, $b) = (object) new ArrayObject([0, 1]);
117+
118+
will now result in $a == 0 and $b == 1. Previously both $a and $b were null.
119+
120+
Relevant RFCs:
121+
* https://wiki.php.net/rfc/abstract_syntax_tree#changes_to_list
122+
* https://wiki.php.net/rfc/fix_list_behavior_inconsistency
123+
124+
Changes to parameter handling
125+
-----------------------------
126+
127+
* It is no longer possible to define two function parameters with the same name.
128+
For example, the following method will trigger a compile-time error:
129+
130+
public function foo($a, $b, $unused, $unused) {
131+
// ...
132+
}
133+
134+
Code like this should be changed to use distinct parameter names, for example:
135+
136+
public function foo($a, $b, $unused1, $unused2) {
137+
// ...
138+
}
139+
140+
* The func_get_arg() and func_get_args() functions will no longer return the
141+
original value that was passed to a parameter and will instead provide the
142+
current value (which might have been modified). For example
143+
144+
function foo($x) {
145+
$x++;
146+
var_dump(func_get_arg(0));
147+
}
148+
foo(1);
149+
150+
will now print "2" instead of "1". This code should be changed to either
151+
perform modifications only after calling func_get_arg(s)
152+
153+
function foo($x) {
154+
var_dump(func_get_arg(0));
155+
$x++;
156+
}
157+
158+
or avoid modifying the parameters altogether:
159+
160+
function foo($x) {
161+
$newX = $x + 1;
162+
var_dump(func_get_arg(0));
163+
}
164+
165+
* Similarly exception backtraces will no longer display the original value that
166+
was passed to a function and show the modified value instead. For example
167+
168+
function foo($x) {
169+
$x = 42;
170+
throw new Exception;
171+
}
172+
foo("string");
173+
174+
will now result in the stack trace
175+
176+
Stack trace:
177+
#0 file.php(4): foo(42)
178+
#1 {main}
179+
180+
while previously it was:
181+
182+
Stack trace:
183+
#0 file.php(4): foo('string')
184+
#1 {main}
185+
186+
While this should not impact runtime behavior of your code, it is worthwhile
187+
to be aware of this difference for debugging purposes.
188+
189+
The same limitation also applies to debug_backtrace() and other functions
190+
inspecting function arguments.
191+
192+
Relevant RFC: https://wiki.php.net/phpng
193+
194+
Changes to integer operations
195+
-----------------------------
196+
197+
* Bitwise shifts by negative numbers will now throw a warning and return false:
198+
199+
var_dump(1 >> -1); // bool(false)
200+
// Warning: Bit shift by negative number
201+
202+
* Left bitwise shifts by a number of bits beyond the bit width of an integer
203+
will always result in 0:
204+
205+
var_dump(1 << 64); // int(0)
206+
207+
Previously the behavior of this code was dependent on the used CPU
208+
architecture. For example on x86 (including x86-64) the result was int(1),
209+
because the shift operand was wrapped.
210+
211+
* Similarly right bitwise shifts by a number of bits beyond the bit width of an
212+
integer will always result in 0 or -1 (depending on sign):
213+
214+
var_dump(1 >> 64); // int(0)
215+
var_dump(-1) >> 64); // int(-1)
216+
217+
Relevant RFC: https://wiki.php.net/rfc/integer_semantics
218+
219+
Other core changes
220+
------------------
221+
35222
. Removed ASP (<%) and script (<script language=php>) tags.
36223
(RFC: https://wiki.php.net/rfc/remove_alternative_php_tags)
37224
. call_user_method() and call_user_method_array() no longer exists.
38-
. PHP 7 doesn't keep original values of arguments passed to user functions,
39-
so func_get_arg() and func_get_args() will return current value of argument
40-
instead of the actually passed. The following code is going to be affected:
41-
function foo($x) { $x = 2; return func_get_arg(0);} var_dump(foo(1));
42-
It will now produce 2, not 1.
43-
. Function parameters with duplicate name are not allowed anymore. Definitions
44-
like “function foo($x,$x) {}” will lead to compile time error.
45-
. Indirect variable, property and method references are now interpreted with
46-
left-to-right semantics. See details in:
47-
https://wiki.php.net/rfc/uniform_variable_syntax#semantic_differences_in_existing_syntax
48-
. The global keyword now only accepts simple variables. See details in:
49-
https://wiki.php.net/rfc/uniform_variable_syntax#global_keyword_takes_only_simple_variables
50225
. The addition of Unicode Codepoint Escape Syntax for double-quoted strings
51226
and heredocs means that \u{ followed by an invalid sequence will now error.
52227
However, \u without a following { is unaffected, so "\u202e" won't error and
@@ -74,6 +249,9 @@ PHP X.Y UPGRADE NOTES
74249
(RFC: https://wiki.php.net/rfc/remove_hex_support_in_numeric_strings)
75250
. $HTTP_RAW_POST_DATA is no longer available. Use the php://input stream instead.
76251

252+
Other
253+
=====
254+
77255
- Date:
78256
. Removed $is_dst parameter from mktime() and gmmktime().
79257

0 commit comments

Comments
 (0)