slice 的問題
在一次介面輸出時,使用了slice的方法,結果導致返回的 json 陣列變成了物件。
檢視 slice 原始碼:
/**
* Slice the underlying collection array.
*
* @param int $offset
* @param int $length
* @return static
*/
public function slice($offset, $length = null)
{
return new static(array_slice($this->items, $offset, $length, true));
}
請注意到 array_slice 的第四個引數傳了 true,此引數為 preserve_keys,預設為 false。array_slice 預設會重新排序並重置陣列的數字索引,設定為 true 則儲存原 key。
php 陣列預設是索引陣列,有預設的自增數字 key,一旦陣列key被修改很大可能變成關聯陣列,此時不再擁有自增數字 key。
因此 array_slice 傳入索引陣列,並且start不從0開始,preserve_keys=true,則返回關聯陣列。
索引陣列轉為json後是陣列,而關聯陣列轉為json後是物件。
php -a
php > $a = [1,2,3,4,5,6];
php > $e = array_slice($a, 1, 4, true);
php > echo json_encode($e);
{"1":2,"2":3,"3":4,"4":5}
php > $e = array_slice($a, 0, 4, true);
php > echo json_encode($e);
[1,2,3,4]
php > $e = array_slice($a, 1,4);
php > echo json_encode($e);
[2,3,4,5]
要小心類似的 array 函式還有很多,例如 array_filter。
解決辦法
array_values 可以將任何陣列轉變為索引陣列,但要小心會拋棄原來的 key。
在 Laravel 的Collection 中可以使用 values 方法:
$models = Model::where()->get();
$models->slice(1,3)->values(); //返回索引陣列
本作品採用《CC 協議》,轉載必須註明作者和本文連結