This article mainly introduces the remarks of PHP7.0, which greatly improves the performance of the new version and changes the language features. the following content is the remarks of LCT translation on the official version upgrade, for more information, see PHP7.0, which not only greatly improves the performance but also changes the language features. For more information, see the following:
1. backward incompatible changes
Language changes
Variable processing changes
Indirect variables, attributes, and method references are now interpreted in left-to-right semantics. Some examples:
$ Foo ['bar'] ['Baz'] // explain it ($ foo) ['bar'] ['Baz'] $ foo-> $ bar ['Baz'] // explain ($ foo-> $ bar) ['Baz'] $ foo-> $ bar ['Baz'] () // explain to do ($ foo-> $ bar) ['Baz'] () Foo :: $ bar ['Baz'] () // explain (Foo: $ bar) ['Baz'] ()
To restore the previous behavior, you need to explicitly increase the brackets:
${$foo['bar']['baz']}$foo->{$bar['baz']}$foo->{$bar['baz']}()Foo::{$bar['baz']}()
Currently, global keywords only accept simple variables. Like the previous
The code is as follows:
Global $ foo-> bar;
The requirements are as follows:
The code is as follows:
Global $ {$ foo-> bar };
Variable or function call plus parentheses no longer have any impact. For example, in the following code, the function call result is passed to a function as a reference.
Function getArray () {return [1, 2, 3];} $ last = array_pop (getArray (); // Strict Standards: only variables can be passed in reference mode $ last = array_pop (getArray ()));
// Strict Standards: only variables can be passed by reference.
Now a strict standard error is thrown regardless of whether brackets are used. In the past, there was no prompt in the second call method.
The sequence of automatic installation and reference creation of array elements or object properties is different. For example:
$ Array = []; $ array ["a"] = & $ array ["B"]; $ array ["B"] = 1; var_dump ($ array ); the result is ["a" => 1, "B" => 1]. the previous result is ["B" => 1, "a" => 1].
Related RFC:
Https://wiki.php.net/rfc/uniform_variable_syntax
Https://wiki.php.net/rfc/abstract_syntax_tree
List () changes
List () is no longer assigned in reverse order, for example:
The code is as follows:
List ($ array [], $ array [], $ array []) = [1, 2, 3];
Var_dump ($ array );
The result is $ array = [1, 2, 3] instead of [3, 2, 1]. Note that only the assignment order has changed, while the assignment is still consistent (LCTT: that is, the previous list () behavior is to assign values one by one from the following variables, in this way, [3, 2, 1] will be generated for the above usage .). For example
The code is as follows:
List ($ a, $ B, $ c) = [1, 2, 3];
// $ A = 1; $ B = 2; $ c = 3;
Still keep the current behavior.
You are no longer allowed to assign values to an empty list. All of the following are invalid:
List () = $ a; list (,) = $ a; list ($ x, list (), $ y) = $ a; list () string splitting is no longer supported (previously supported only in some cases)
The following code:
The code is as follows:
$ String = "xy ";
List ($ x, $ y) = $ string;
The result is: $ x = null and $ y = null (no prompt). the previous result is: $ x = "x" and $ y = "y ".
In addition, list () can always process objects that implement ArrayAccess, for example:
The code is as follows:
List ($ a, $ B) = (object) new ArrayObject ([0, 1]);
The result is: $ a = 0 and $ B = 1. In the past, both $ a and $ B were null.
Related RFC:
Https://wiki.php.net/rfc/abstract_syntax_tree#changes_to_list
Https://wiki.php.net/rfc/fix_list_behavior_inconsistency
Foreach changes
Foreach () iteration does not affect the internal pointer of the array. the array pointer can be accessed through a series of functions such as current ()/next. For example:
The code is as follows:
$ Array = [0, 1, 2];
Foreach ($ array as & $ val ){
Var_dump (current ($ array ));
}
Now point to the value int (0) three times. The previous outputs are int (1), int (2), and bool (false ).
During array value-based iteration, foreach is always operating on the array copy, and any operations on the array in the iteration will not affect the iteration behavior. For example:
The code is as follows:
$ Array = [0, 1, 2];
$ Ref = & $ array; // Necessary to trigger the old behavior
Foreach ($ array as $ val ){
Var_dump ($ val );
Unset ($ array [1]);
}
Now all three elements (0 1 2) will be printed, and the previous second element 1 will be skipped (0 2 ).
When the array is iterated by reference, the modification to the array will continue to affect the iteration. However, PHP can better maintain the position in the array when using numbers as keys. For example, add an array element during reference iteration:
The code is as follows:
$ Array = [0];
Foreach ($ array as & $ val ){
Var_dump ($ val );
$ Array [1] = 1;
}
Now the iterations correctly add elements. The output of the above code is "int (0) int (1)", but previously only "int (0 )".
For normal (non-traversal) objects, performing by value or by reference iteration is similar to performing by reference iteration on arrays. This is in line with previous behavior, except for the more precise location management improvements described above.
The iteration behavior of the object that can be traversed remains unchanged.
Related RFC: https://wiki.php.net/rfc/php7_foreach
Parameter processing changes
Two function parameters with the same name cannot be defined. For example, the following method will trigger a compilation error:
The code is as follows:
Public function foo ($ a, $ B, $ unused, $ unused ){
//...
}
The code above should be modified using different parameter names, such:
The code is as follows:
Public function foo ($ a, $ B, $ unused1, $ unused2 ){
//...
}
The func_get_arg () and func_get_args () functions no longer return the original value passed to the parameter, but return the current value (which may be modified ). For example:
The code is as follows:
Function foo ($ x ){
$ X ++;
Var_dump (func_get_arg (0 ));
}
Foo (1 );
"2" instead of "1" is printed ". The code should be modified only after func_get_arg (s) is called.
The code is as follows:
Function foo ($ x ){
Var_dump (func_get_arg (0 ));
$ X ++;
}
Or avoid modifying the parameters:
The code is as follows:
Function foo ($ x ){
$ NewX = $ x + 1;
Var_dump (func_get_arg (0 ));
}
Similarly, exception backtracking does not display the original value passed to the function, but the modified value. For example:
The code is as follows:
Function foo ($ x ){
$ X = 42;
Throw new Exception;
}
Foo ("string ");
The result of the stack trace is:
The code is as follows:
Stack trace:
#0 file. php (4): foo (42)
#1 {main}
Previously:
The code is as follows:
Stack trace:
#0 file. php (4): foo ('string ')
#1 {main}
This does not affect the running behavior of your code. it is worth noting that the code will be different during debugging.
The same restriction affects debug_backtrace () and other functions that check function parameters.
Related RFC: https://wiki.php.net/phpng
Changes in integer processing
Invalid octal representation (containing numbers greater than 7) now produces a compilation error. For example, the following code is no longer valid:
$ I = 0781; // 8 is not a valid octal number!
Previously, invalid numbers (and any numbers after Invalid numbers) were ignored. The previous $ I value is 7, because the last two digits are quietly discarded.
An arithmetic error is thrown when the binary value is displaced by a negative image:
The code is as follows:
Var_dump (1>-1 );
// ArithmeticError: displacement with a negative number
The result is always 0 when the number of bits to the left is greater than the Integer width.
The code is as follows:
Var_dump (1 <64); // int (0)
The results of the previous code depend on the CPU architecture used. For example, the result on x86 (including the x86-64) is int (1) because its displacement operand is within the range.
Similarly, when the number of digits to the right displacement exceeds the Integer width, the result is always 0 or-1 (dependent on the symbol ):
The code is as follows:
Var_dump (1> 64); // int (0)
Var_dump (-1> 64); // int (-1)
Related RFC: https://wiki.php.net/rfc/integer_semantics
Changes in string processing
A string containing a hexadecimal number is not treated as a number, nor is it specially processed. See the new behavior in the example:
The code is as follows:
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 ")
// Note: an invalid number is displayed.
Filter_var () can be used to check whether a string contains hexadecimal numbers or whether the string can be converted to 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)
The Unicode Codepoint Escape format (Unicode Codepoint Escape Syntax) is added to the double quotation mark string and the HERE document. Therefore, "\ u {" with an invalid sequence may cause an error:
$ Str = "\ u {xyz}"; // fatal error: Invalid UTF-8 point escape sequence
To avoid this situation, you need to escape the backslash at the beginning:
$ Str = "\ u {xyz}"; // correct
However, the "\ u" that does not follow {is not affected. The following code does not generate errors and works as before:
$ Str = "\ u202e"; // correct
Related RFC:
Https://wiki.php.net/rfc/remove_hex_support_in_numeric_strings
Https://wiki.php.net/rfc/unicode_escape
Error handling changes
There are two Exception classes: Exception and Error. Both classes implement a new interface: Throwable. The type indication in the exception handling code may need to be modified to handle this situation.
Some fatal errors and recoverable fatal errors are now throw an Error. Because Error is an Exception-independent class, these exceptions are not caught by existing try/catch blocks.
Recoverable fatal errors are converted to an exception, so they cannot be ignored in error handling. In some cases, the type indication fails and can no longer be ignored.
Parsing errors now generate a ParseError for the Error extension. Except for the previous processing based on the returned value/errorgetlast (), the eval () error processing for some code that may be invalid should be changed to capturing ParseError.
Constructor of internal classes always throws an exception when they fail. Some previous constructors will return NULL or an unavailable object.
The error level of some E_STRICT prompts has changed.
Related RFC:
Https://wiki.php.net/rfc/engine_exceptions_for_php7
Https://wiki.php.net/rfc/throwable-interface
Https://wiki.php.net/rfc/internal_constructor_behaviour
Https://wiki.php.net/rfc/reclassify_e_strict
Other language changes
Static calling of a non-static call with an incompatible $ this context is no longer supported. In this case, $ this is not defined, but the call to it is allowed with an discard prompt. Example:
Class A {public function test () {var_dump ($ this) ;}}// note: class B {public function callNonStaticMethodOfA () {:: test () ;}} (new B)-> callNonStaticMethodOfA ();
// Discard: non-static method A: test () should not be called statically
// Prompt: undefined variable $ this
NULL
Note that this only appears in calls from incompatible contexts. If class B extends itself to Class A, the call is allowed without any prompt.
You cannot use the following class name, interface name, or special name (case sensitive ):
Bool
Int
Float
String
Null
False
True
This is used in class/interface/trait declaration, class_alias (), and use statements.
In addition, the following class names, interface names, and special names will be retained for future use, but no error will be thrown during usage:
Resource
Object
Mixed
Numeric
When the yield statement structure is used in an expression context, parentheses are no longer required. It is now a right-join operator with a priority between "print" and "=>. In some cases, this may lead to different behaviors, such:
Echo yield-1;
// Previously explained as follows
Echo (yield)-1;
// The description is as follows:
Echo yield (-1 );
Yield $ foo or die;
// Previously explained as follows
Yield ($ foo or die );
// The description is as follows:
(Yield $ foo) or die;
This problem can be solved by adding parentheses.
ASP (<%) and script (