Array attribute definition discrimination in incompatible php5.6 and earlier versions mentioned in the incompatibility page (http://php.net/manual/zh/migration56.incompatible.php) of php5.6 official documentation several incompatibility with earlier versions, this article mentions incompatibility when defining array attributes for classes. The original article and example are as follows:
In versions earlier than PHP 5.6, when defining an array type attribute for a class, if both the explicit array key and the implicit array key are used in the array, in addition, if the explicit and implicit sequence keys are the same, the keys of the array will be overwritten. For example:
1
'foo', 6 'bar', 7 'quux', 8 ]; 9 }10 11 var_dump((new C)->array);12 ?>
The above example is output in PHP 5.5:
1 array(2) {2 [0]=>3 string(3) "bar"4 [1]=>5 string(4) "quux"6 }
Output in PHP 5.6:
array(3) { [1]=> string(3) "foo" [2]=> string(3) "bar" [3]=> string(4) "quux"}
The above example is actually a very special case. There are several prerequisites for its appearance:
1. the array attribute must be defined for the class and initialized when the class variable is defined;
2. it must be before the explicit array key, after the implicit array key, the implicit array key overwrites the value of the display array key at the same position as itself; if the implicit array key is before, after the explicit array key is defined, overwriting will occur, regardless of the version;
3. the explicit array key must be a constant (including a class constant). if it is a literal constant, no matter what version, in the above circumstances, the implicit array key does not appear to overwrite the explicit array key;
Test the output of the following example in PHP 5.5:
1.1 Non-class array member definitions:
1 $array = [2 ONE=>'foo',3 'bar',4 'quux'5 ];6 var_dump($array);
Output:
array(3) { [1] => string(3) "foo" [2] => string(3) "bar" [3] => string(4) "quux"}
1.2 Non-initialization value assignment:
1 define('ONE', 1);2 class C {3 public $array;4 }5 $c = new C;6 $c->array = [ONE=>'foo','bar','quux'];7 var_dump($c->array);
Output:
array(3) { [1] => string(3) "foo" [2] => string(3) "bar" [3] => string(4) "quux"}
1 define('ONE', 1); 2 class C { 3 const ONE = 1; 4 public $array; 5 public function __construct() { 6 $this->array = array( 7 'bar', 8 ONE => 'foo', 9 'quux',10 );11 }12 }13 $c = new C;14 var_dump($c->array);
Output:
array(3) { [0] => string(3) "bar" [1] => string(3) "foo" [2] => string(4) "quux"}
2. explicit key-to-implicit key override:
1 define('ONE', 1); 2 class C { 3 const ONE = 1; 4 public $array = array( 5 'bar', 6 'quux', 7 ONE => 'foo', 8 'guru' 9 );10 }11 $c = new C;12 var_dump((new C)->array);
Output:
array(3) { [0] => string(3) "bar" [1] => string(3) "foo" [2] => string(4) "guru"}
3. the literal constant is used as the explicit key name:
1 class C { 2 public $array = array( 3 'bar', 4 'quux', 5 1 => 'foo', 6 'guru' 7 ); 8 } 9 $c = new C;10 var_dump((new C)->array);
Output:
array(3) { [0] => string(3) "bar" [1] => string(3) "foo" [2] => string(4) "guru"}
1 class C {2 public $array = array(3 1 => 'foo',4 'bar',5 'quux',6 );7 }8 $c = new C;9 var_dump((new C)->array);
Output:
array(3) { [1] => string(3) "foo" [2] => string(3) "bar" [3] => string(4) "quux"}
In essence, this is a small hidden bug.
In the array definition, if a number key name is specified for some units, the subsequent implicit key name will continue the previous maximum number (including implicit or explicit) key name, the implicit key name should not be used to overwrite the explicit numeric key name, whether the explicit key name is a literal constant or a symbolic constant.
See the official manual array section: http://php.net/manual/zh/?age.types.array.php:
1
"c",6 "d",7 );8 var_dump($array);9 ?>
The above routine will output:
array(4) { [0]=> string(1) "a" [1]=> string(1) "b" [6]=> string(1) "c" [7]=> string(1) "d"}
However, in versions earlier than 5.6, when an array member is initialized as a class, a symbolic constant is used as a number key to name some units, which is inconsistent with the array semantic definition.
In view of this situation is extremely rare, so its impact is small, but once it appears, the resulting bug is extremely difficult to find.