LazyCollection::take() returns wrong items for a negative limit larger than the collection
Laravel Version
13.31.0
PHP Version
8.4.25
Database Driver & Version
No response
Description
take() with a negative limit returns the last $limit items. When the collection holds fewer items than the limit, Collection returns the whole collection, but LazyCollection returns a null entry, drops real items, and emits warnings from inside the framework.
(new Collection(['a', 'b', 'c']))->take(-5)->all(); // ['a', 'b', 'c']
(new LazyCollection(['a', 'b', 'c']))->take(-5)->all(); // ['' => null, 0 => 'a']Warning: Undefined array key 3 in .../Illuminate/Collections/LazyCollection.php on line 1577
Warning: Trying to access array offset on null in .../Illuminate/Collections/LazyCollection.php on line 1577The two classes implement the same Enumerable contract, so swapping one for the other silently changes the result here.
This only happens when abs($limit) is greater than the number of items. Every combination where abs($limit) <= count() agrees between the two classes, which is why the existing testTakeLast case (take(-2) on three items) does not catch it.
For reference, the results across sizes and limits, Collection first:
| items | limit | Collection |
LazyCollection |
|---|---|---|---|
| 1 | -2 | ['a'] |
['' => null] |
| 2 | -3 | ['a', 'b'] |
['' => null, 0 => 'a'] |
| 3 | -5 | ['a', 'b', 'c'] |
['' => null, 0 => 'a'] |
| 4 | -5 | ['a', 'b', 'c', 'd'] |
['' => null, 0 => 'a', 1 => 'b', 2 => 'c'] |
| 5 | -7 | ['a', 'b', 'c', 'd', 'e'] |
['' => null, 0 => 'a', 1 => 'b', 2 => 'c'] |
Steps To Reproduce
composer require illuminate/collections<?php
require 'vendor/autoload.php';
use Illuminate\Support\Collection;
use Illuminate\Support\LazyCollection;
var_dump((new Collection(['a', 'b', 'c']))->take(-5)->all());
var_dump((new LazyCollection(['a', 'b', 'c']))->take(-5)->all());Expected: both return ['a', 'b', 'c'].
Actual: the LazyCollection call emits four warnings and returns ['' => null, 0 => 'a'].
A fix was proposed in #61489.
Source: laravel/framework