PHPはあまりマトモなスコープは持っていないので、変数に適当な名前を付けると見つけにくいバグが入り込んでしまうことがある。
# Perl foreach $value (@array1) { ... } # foreachで使った$valueは無効になっている foreach $value (@array2) { ... }
// PHP foreach ($array1 as &$value) // $array1を変更するためにリファレンスを使用 ... // foreachで使った$valueはまだ有効 foreach ($array2 as $value) // $valueは$array1の最後の要素のリファレンス ... // 結果、$array1の最後の要素が二番目のループで変更されてしまう
これを回避するのにはunset()が使える。(但しあまり美しくない)
// PHP foreach ($array1 as &$value) ... unset($value); // 明示的に無効化する foreach ($array2 as $value) ...
PHPでは条件演算子の結合がPerlとは異なる。
printf('%s ', 1 ? 1 ? 'A' : 'B' : 'C'); printf('%s ', 1 ? 0 ? 'A' : 'B' : 'C'); printf('%s ', 0 ? 1 ? 'A' : 'B' : 'C'); printf('%s' , 0 ? 0 ? 'A' : 'B' : 'C');
# Perl A B C C
// PHP A B C C
ifの入れ子に相当する書き方はOK。しかし、
printf('%s ', 1 ? 'A' : 1 ? 'B' : 'C'); printf('%s ', 1 ? 'A' : 0 ? 'B' : 'C'); printf('%s ', 0 ? 'A' : 1 ? 'B' : 'C'); printf('%s' , 0 ? 'A' : 0 ? 'B' : 'C');
# Perl A A B C
// PHP B B B C
このようにelse ifに相当する書き方をするとPerl(Cもそうだが)とは異なった結果になってしまう。
普通の感覚では、
printf('%s ', 1 ? 'A' : (1 ? 'B' : 'C')); printf('%s ', 1 ? 'A' : (0 ? 'B' : 'C')); printf('%s ', 0 ? 'A' : (1 ? 'B' : 'C')); printf('%s' , 0 ? 'A' : (0 ? 'B' : 'C'));
という結合を期待すると思うが、結果から
printf('%s ', (1 ? 'A' : 1) ? 'B' : 'C'); printf('%s ', (1 ? 'A' : 0) ? 'B' : 'C'); printf('%s ', (0 ? 'A' : 1) ? 'B' : 'C'); printf('%s' , (0 ? 'A' : 0) ? 'B' : 'C');
と評価されていることが分かる。(左結合?)
PHPでは条件演算子はifの代わりではなく、あくまでも演算子ということか。