当心 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 协议》,转载必须注明作者和本文链接
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!