今回は list の話です。
次のように、配列の形で値を返す関数があるとします。
function test() {
return array(1, 2, 3);
}
この関数から返る値を 配列を使わずに受ける場合 list という PHP の言語要素を使用します。
list($a, $b, $c) = test();
変数 $a,$b,$c に それぞれ 1,2,3 が格納されます。
list は関数ではなく言語の構造なので 変わった記述ができます。 例えば次のように 受け側の数が少なくても OK です。
list($a, $b) = array(1, 2, 3, 4); var_dump($a, $b);
int(1) int(2)
受け側の変数が 2 つなので 配列も 2 つ目までが格納されます。
次のように変数を省略することもできます。
list(, $a, , $b) = array(1, 2, 3, 4); var_dump($a, $b);
int(2) int(4)
この場合、変数を省略した 1 つ目、3 つ目は飛ばされて 2 つ目と 4 つ目の値が格納されました。
あと、list は数字がキーの要素のみ扱うので 文字列がキーの配列は無視されてしまいます。
例えば次の例では、2 つ目と 3 つ目の文字列がキーの 要素は無視されるので $a,$b には 0,1 が入ります。
list($a, $b) = array(0 => 0, 'a' => 1, 'b' => 2, 1 => 3);
次の例の場合、キーが 1 の要素が存在しないため NOTICE が発生して $b には NULL が入ります。
list($a, $b) = array(0 => 0, 2 => 2);
要するに list は次のような処理になるわけです。
list($a, $b, $c) = $array; // ↑ // この 2 つは同じ処理 // ↓ $a = $array[0]; $b = $array[1]; $c = $array[2];
そのため、キーが負の数字の場合も無視されます。
list($a, $b) = array(1 => 1, -5 => -5, 0 => 0);
この場合、$a,$b には 0,1 が入ります。
なかなか便利な list ですが、 受け側も配列の場合、気をつけなくてはならないことがあります。
list は 右側から順に値を格納していきます。
つまり次のような場合、キーの値と定義順が逆になります。
list($a[0], $a[1]) = array(1, 2, 3, 4); print_r($a);
Array ( [1] => 2 [0] => 1 )
格納される値は変わりませんが キーが 1,0 の順で定義されています。 そのため、for と foreach で結果が変わってしまうようなことになります。
for ($i = 0, $c = count($a); $i < $c; $i++) echo $a[$i];
int(1) int(2)
foreach ($a as $v) echo $v;
int(2) int(1)
さらにキーを省略した場合は もっと大変なことになります。
list($a[], $a[], $a[]) = array(1, 2, 3, 4); print_r($a);
Array ( [0] => 3 [1] => 2 [2] => 1 )
右側から順に格納されるため キーまで逆に付いてしまいます。
オマケですが、次のように list をネストさせることもできます。
list($a, list($b, $c)) = array(1, array(2, 3));