Heim > Backend-Entwicklung > PHP-Tutorial > php 5.6 与之前版本不兼容中的数组属性定义辨析

php 5.6 与之前版本不兼容中的数组属性定义辨析

WBOY
Freigeben: 2016-06-23 13:28:07
Original
1147 Leute haben es durchsucht

在php5.6官方文档的不兼容页(http://php.net/manual/zh/migration56.incompatible.php)中提到了几个与以前版本不兼容的情况,其中提到了为类定义数组属性时,不兼容的情况,原文及示例如下:

在 PHP 5.6 之前的版本中,为类定义数组类型的属性时, 如果数组中同时使用了显式数组键和隐式数组键,并且显式的键和隐式的序列键相同, 那么数组的键将被覆盖。例如:

 1 <?php 2 class C { 3     const ONE = 1; 4     public $array = [ 5         self::ONE => 'foo', 6         'bar', 7         'quux', 8     ]; 9 }10 11 var_dump((new C)->array);12 ?>
Nach dem Login kopieren

以上示例在PHP 5.5中输出:

1 array(2) {2   [0]=>3   string(3) "bar"4   [1]=>5   string(4) "quux"6 }
Nach dem Login kopieren

在PHP 5.6中输出:

array(3) {  [1]=>  string(3) "foo"  [2]=>  string(3) "bar"  [3]=>  string(4) "quux"}
Nach dem Login kopieren

以上的例子,其实是非常特例的情况,其出现的前提条件有几条:

1. 必须是为类定义数组属性,并且是在类变量定义时初始化该属性的情况;

2. 一定是显式数组键在前,隐式数组键在后,隐式数组键对与自身位置相同的显示数组键的值的覆盖的情况;如果隐式数组键在前,显式数组键定义在后,则覆盖是一定会发生的,与版本无关;

3. 显式数组键必须是常量(包括类常量)方式,如果是字面量常量,则无论什么版本,在以上情况下,都不会出现隐式数组键覆盖显式数组键;

考察以下示例在PHP 5.5中的输出:

1.1 非类数组成员定义:

1 $array = [2 ONE=>'foo',3  'bar',4  'quux'5 ];6 var_dump($array);
Nach dem Login kopieren

输出:

array(3) {  [1] =>  string(3) "foo"  [2] =>  string(3) "bar"  [3] =>  string(4) "quux"}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

1.2 非初始化时赋值:

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);
Nach dem Login kopieren

输出:

array(3) {  [1] =>  string(3) "foo"  [2] =>  string(3) "bar"  [3] =>  string(4) "quux"}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

 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);
Nach dem Login kopieren

输出:

array(3) {  [0] =>  string(3) "bar"  [1] =>  string(3) "foo"  [2] =>  string(4) "quux"}
Nach dem Login kopieren

2. 显式键对隐式键的覆盖:

 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);
Nach dem Login kopieren

输出:

array(3) {  [0] =>  string(3) "bar"  [1] =>  string(3) "foo"  [2] =>  string(4) "guru"}
Nach dem Login kopieren
Nach dem Login kopieren

3. 字面量常量作为显式键名:

 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);
Nach dem Login kopieren

输出:

array(3) {  [0] =>  string(3) "bar"  [1] =>  string(3) "foo"  [2] =>  string(4) "guru"}
Nach dem Login kopieren
Nach dem Login kopieren

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);
Nach dem Login kopieren

输出:

array(3) {  [1] =>  string(3) "foo"  [2] =>  string(3) "bar"  [3] =>  string(4) "quux"}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

其实本质上,这是一个隐藏的很深的小bug。

在数组的定义中,如果有部分单元指定了数字键名,其后的隐式键名会延续此前最大数字(包括隐式或显式)键名,而不应产生隐式键名覆盖显式数字键名情况,无论显式键名是字面量常量还是符号常量。

见官方手册数组一节:http://php.net/manual/zh/language.types.array.php:

1 <?php2 $array = array(3          "a",4          "b",5     6 => "c",6          "d",7 );8 var_dump($array);9 ?>
Nach dem Login kopieren

以上例程会输出:

array(4) {  [0]=>  string(1) "a"  [1]=>  string(1) "b"  [6]=>  string(1) "c"  [7]=>  string(1) "d"}
Nach dem Login kopieren

只不过,5.6之前的版本在实现为类初始化数组成员时,用符号常量作数字键,对部分单元进行命名,出现了与数组语义定义不符的情况。

鉴于此种情况极其少见,故其影响较小,但一旦出现,则由此引起的bug极其难查。

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage