読者です 読者をやめる 読者になる 読者になる

php5.6の変更点 メンバ変数に配列を宣言した時、キーに定数をいれても、次の要素のキーは前のキー+1で始まる

そもそも5.5以前でそうならないのを知らなかった。


php5.5でメンバ変数を宣言するときに配列で定義したときの動きが下の通り。

ちなみに公式では"設定すると"って言葉をつかってるけど、英語版を読むと、defineとあるとおり、5.5でもこの動きをするのはメンバ変数の宣言時だけ。

PHP: 下位互換性のない変更点 - Manual


<?php
class C {
    const ONE = 1;
    public $array = [
        self::ONE => 'foo',
        'bar',
        'quux',
    ];
}

var_dump((new C)->array);

//php5.5

array(2) {
  [0]=>
  string(3) "bar"
  [1]=>
  string(4) "quux"
}

//php5.6
array(3) {
  [1]=>
  string(3) "foo"
  [2]=>
  string(3) "bar"
  [3]=>
  string(4) "quux"
}
?>

宣言した時に配列の一部のキーで定数や変数を参照させると、次の要素のキーは直前の要素のキー+1じゃなくて、0スタートで未定義の数になる。


いろいろやってみたが、この動きはメンバ変数を宣言したときだけ。


こんな感じだった。

<?php
//php5.5

class PHP55 {
	const const_TWO = 2;

	public $arr1 =
		array(
				0, self::const_TWO=> 1,2,3,4
		);

	public $arr2 =
	array(
			0, self::const_TWO=> 1,2
	);

	public $arr3 =
	array(
			0, 2=> 1,2,3,4
	);


	public function reset_arr(){
		$this->arr1 = array(
			0,self::const_TWO => 1,2,3,4
		);
		$this->arr2 = array(
				0,self::const_TWO => 1,2
		);

	}


}

$php55 = new PHP55;
//宣言時
var_dump($php55->arr1,$php55->arr2,$php55->arr3);
/*
//$php55->arr1
//const_TWOのつぎのキーは[3]じゃなくて[1]になる。
//そのつぎのキーで、[2]が重複する。後勝ちで先に[2]にいれた要素の1が消える。
array(4) {
  [0]=>
  int(0)
  [1]=>
  int(2)
  [2]=>
  int(3)
  [3]=>
  int(4)
}
//$php55->arr2
//const_TWOのつぎのキーは[3]じゃなくて[1]になる。
array(3) {
  [0]=>
  int(0)
  [2]=>
  int(1)
  [1]=>
  int(2)
}

//$php55->arr3
//キーを直接定義した場合はふつうの動き。
//[2]の後ろでいれた要素は、[3]に格納される。
array(5) {
  [0]=>
  int(0)
  [2]=>
  int(1)
  [3]=>
  int(2)
  [4]=>
  int(3)
  [5]=>
  int(4)
}

//リセット時
$php55->reset_arr();
var_dump($php55->arr1,$php55->arr2);
/*
//arr1
//宣言時以外は普通の動き
array(5) {
  [0]=>
  int(0)
  [2]=>
  int(1)
  [3]=>
  int(2)
  [4]=>
  int(3)
  [5]=>
  int(4)
}

//arr2
//宣言時以外は普通の動き
array(3) {
  [0]=>
  int(0)
  [2]=>
  int(1)
  [3]=>
  int(2)
}

*/