久しぶりに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"
}
今回はあくまで実験だったため以上の書き方としましたが、キーに意味がある要件の場合は、そもそもデータ構造を見なおしたほうが良さそうです。