当心 Collection 的 slice 方法,它会偷偷修改你的数组
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 协议》,转载必须注明作者和本文链接