array_sliceとarray_spliceの違いをきちんと押さえる
array_slice は元配列を変えずに一部を切り出して返す非破壊の関数、array_splice は元配列そのものを書き換えて要素を抜き差しする破壊的な関数です。
名前が似ているだけで別物
この2つ、名前が一文字違いなので混同しがちですが、性質はまるで違います。ざっくり言えば array_slice は元配列に触らず一部を切り出して返す非破壊系、array_splice は元配列そのものを書き換える破壊系です。ここを最初に頭に入れておくと事故が減ると思います。
$data = ['a', 'b', 'c', 'd', 'e'];
$part = array_slice($data, 1, 2);
// $part は ['b', 'c']、$data は元のまま
array_sliceとキーの扱い
スライスすると数値キーは基本的に振り直されます。0, 1, 2… と付け直されるので、元のインデックスを保ちたいときは第4引数 preserve_keys を true にします。文字列キーは常に維持されるので気にしなくて大丈夫です。
$data = ['a', 'b', 'c', 'd'];
var_dump(array_slice($data, 2));
// [0 => 'c', 1 => 'd'] キーは0起点に
var_dump(array_slice($data, 2, null, true));
// [2 => 'c', 3 => 'd'] 元のキーを保持
ここで痛い目に遭うのが「元の位置番号で処理したいのにキーがずれていた」というパターンです。ページング処理などで元インデックスが意味を持つなら preserve_keys を意識しておきたいですね。
array_spliceで抜き差しする
一方の array_splice は、指定範囲を取り除いて、必要なら別の要素を差し込みます。戻り値は「取り除かれた要素」で、元配列は書き換わります。要素の入れ替えや途中挿入をしたいときに便利です。
$list = ['赤', '青', '黄'];
// 1番目から1個削除して、2個差し込む
$removed = array_splice($list, 1, 1, ['緑', '紫']);
// $list は ['赤', '緑', '紫', '黄']
// $removed は ['青']
// 長さ0を指定すれば純粋な挿入になる
array_splice($list, 0, 0, ['白']);
// $list の先頭に '白' が入る
まとめ
切り出して眺めたいだけなら array_slice、配列を組み替えたいなら array_splice、と目的で選ぶと迷いません。slice のキー振り直しと splice の破壊性、この2点だけ覚えておけば大きな落とし穴は避けられると思います。うっかり splice を非破壊のつもりで呼んで元データが変わっていた、というのは私も昔やらかしたので気をつけたいところです。
よくある質問
Q. 元のキーを保ったままスライスしたいです。
A. array_slice の第4引数 preserve_keys を true にします。数値キーは既定で0起点に振り直されますが、これで元の位置番号を維持できます。
Q. array_splice の戻り値は何ですか?
A. 取り除かれた要素の配列です。元配列自体は書き換わるので、非破壊のつもりで呼ぶと元データが変わってしまう点に注意してください。
Q. 削除せず挿入だけしたいときは?
A. array_splice の削除長さに 0 を指定すれば、その位置に要素を差し込むだけになります。