当心 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 协议》,转载必须注明作者和本文链接
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

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