Analysis of array attribute definitions in incompatibility between php5.6 and earlier versions

Source: Internet
Author: User
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.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.