PHPの配列は、キーのインデックスなどが配列側でしっかり管理されています。
$a=[];$a[]=1;$a[10]=2;$a[]=3;var_dump($a);// [0=>1, 10=>2, 11=>3]
キーを空白にすると、自動的に次のインデックスを割り当ててくれます。
とても便利。
しかしこのインデックス、一度増えるとその後値を消しても戻りません。
$a=[0,1];unset($a[1]);$a[]=2;var_dump($a);// [0=>0, 2=>2]
せっかく配列の最後の値を消したのに、使用した情報は残っていて次のキーは2になっています。
MySQLのauto_increment値と同様、一度上限が上がると下がらないということです。
全ての値を消したとしても同様です。
$a=[0,1];unset($a[1]);unset($a[0]);$a[]=2;var_dump($a);// [2=>2]
ところでこいつを見てくれ。
$a=[0,1];unset($a[1]);unset($a[0]);$b=$a;$a[]=2;var_dump($a);// [0=>2] ←
$b=$a
と配列をコピーしたらインデックスの記憶が消え、また0から始まるようになりました。
なんでだよ。
さらにこっちも見てくれ。
$a=[0,1];unset($a[1]);unset($a[0]);$b=$a;$a[]=2;$b[]=3;var_dump($a);// [0=>2]var_dump($b);// [2=>3] ←
消えたと思っていたインデックスは、実はコピー先の$b
に移っていたようです。
なんでだよ。
ところでNormalize arrays' "auto-increment" value on copy on writeというRFCが提出されているのですが、これは配列のコピーの仕組みを変えようという内容です。
具体的には配列のコピーを、以下のコードと同じにします。
$array_copy=[];foreach($arrayas$key=>$value){$array_copy[$key]=>$value;}
このRFCが適用されたらどうなるかというと、
$a=[0,1];unset($a[1]);unset($a[0]);$b=[];foreach($aas$k=>$v){$b[$k]=$v;}$a[]=2;$b[]=3;var_dump($a);// [2=>2]var_dump($b);// [0=>3]
解決してなくない?