タイトルの通りですが一応説明
// これを
$x = ['PHP', 'Ruby', 'Perl'];
// こうしたい
$x = ['PHP', 'Perl', 'Ruby'];
普通にやってみます。
// まともに入れ替える
$temp = $x[1];
$x[1] = $x[2];
$x[2] = $temp;
var_dump($x);
正しい結果になります。が、3つ以上任意に並べかえるのは辛いですね。
array(3) {
[0]=>
string(3) "PHP"
[1]=>
string(4) "Perl"
[2]=>
string(4) "Ruby"
}
もう少しなんとかならんのかなということで、list()
を使ってみます。
list($x[0], $x[2], $x[1]) = $x;
すると…!?
array(3) {
[0] =>
string(3) "PHP"
[1] =>
string(4) "Perl"
[2] =>
string(4) "Perl"
}
予想外の結果になってしまいます。
list()
の説明ページ ( http://php.net/manual/ja/function.list.php ) を読んでみると丁寧に警告が出されていました。
警告
PHP 5 では、list()は、最も右のパラメータから値を代入します。
なるほど…ん? "PHP5" では?
PHP 7 では、list()は、最も**"左"**のパラメータから値を代入します。
えっ。
//PHP 7.0.0RC6
list($x[0], $x[2], $x[1]) = $x;
array(3) {
[0] =>
string(3) "PHP"
[1] =>
string(4) "Ruby"
[2] =>
string(4) "Ruby"
}
挙動がまるで違う罠ですね。ということなので、右辺に直接$x
を渡すようなことはしないほうが賢明です。以下なら、どちらでも動きますね。
list($x[0], $x[1], $x[2]) = [$x[0], $x[2], $x[1]];
// または
list($x[0], $x[2], $x[1]) = $x + [];
// PHP5, PHP7どちらでも同じ結果
array(3) {
[0] =>
string(3) "PHP"
[1] =>
string(4) "Perl"
[2] =>
string(4) "Ruby"
}
結局、わかりづらいのでlist()
は使わない方がいいかも…。
他の言語にもある書き方で下のようにできたらいいんですが。
// PHPではこういう書き方ができない
$x[0], $x[1], $x[2] = $x[0], $x[2], $x[1];
# => PHP Parse error: syntax error, unexpected ','
あまりいい方法が思いつきませんでしたが、メモとして残しておきます。