久しぶりにPHPを触ってみると、配列の扱いで「どうだっけ?」となった箇所が幾つかあったので、色々と実験をしてみました。メモしておきます。
foreachでループカウンタ(っぽいもの)が欲しいとき
foreachがある言語では、宗教的な理由により可能な限りforeachを使いたいものです。ところが、ループカウンタの出力が要件としてある場合はforを使うしか無い、ように見えますが、foreachでいけます。(ただし、後で触れますが落とし穴があります。)
<pre><?php $as = array( "data0" , "data1" , "data2" , "data3" , "data0" ); foreach($as as $key => $a) { echo "id:" . $key . " value:" . $a . "\n"; } // これでいけるし当然か…… echo $as[0] . "\n"; echo $as[1] . "\n"; echo $as[2] . "\n"; echo $as[3] . "\n"; echo $as[4] . "\n";
id:0 value:data0 id:1 value:data1 id:2 value:data2 id:3 value:data3 id:4 value:data0 data0 data1 data2 data3 data0
unsetで要素を削除するとキーごと削除される
配列から要素を削除する場合はunsetを使用します。すると、キーごと削除されてしまうようなのです。上記foreachを使用する場合は気をつけておかなければ足元を掬われそうです。
forのcount($as)で3が取得されるため、id:2までしかループしないうえ、UndefinedのNoticeが出てしまいます。
<pre><?php $as = array( "data0" , "data1" , "data2" , "data3" , "data0" ); $delkeys = array(0, 2); foreach($delkeys as $delkey) { unset($as[$delkey]); } var_dump($as); for($i = 0; $i < count($as); $i++) { echo $i . " : " . $as[$i] . "\n"; }
array(3) { [1]=> string(5) "data1" [3]=> string(5) "data3" [4]=> string(5) "data0" } Notice: Undefined offset: 0 in D:\xampp\htdocs\sample\unset_sample.php on line 20 0 : 1 : data1 Notice: Undefined offset: 2 in D:\xampp\htdocs\sample\unset_sample.php on line 20 2 :
キーを削除しない(イメージとしては、削除された要素分、キーを詰めて再設定?)ようにするためには下記の方法を使えば良いようです。
<pre><?php $as = array( "data0" , "data1" , "data2" , "data3" , "data0" ); array_splice($as, 1, 1); var_dump($as);
array(4) { [0]=> string(5) "data0" [1]=> string(5) "data2" [2]=> string(5) "data3" [3]=> string(5) "data0" }
今回はあくまで実験だったため以上の書き方としましたが、キーに意味がある要件の場合は、そもそもデータ構造を見なおしたほうが良さそうです。