Framework: Problem with collections

Created on 16 Jul 2019  路  6Comments  路  Source: laravel/framework

  • Laravel Version: 5.8.28
  • PHP Version: 7.2.10

Description:

Hello! I discovered a little problem with collections which tied with JsonSerializable interface.
If you will create new collection with such data and method jsonSerialize() will not return array you got an error.

Steps To Reproduce:

$today = Carbon::now();
$collection = collect($today);
dd($collection);

image

Expected:
image

Fix:
Probably additional cast to array in
https://github.com/laravel/framework/blob/5.8/src/Illuminate/Support/Collection.php#L2130

return (array)$items->jsonSerialize();

Most helpful comment

@staudenmeir why are you so sure?
https://github.com/laravel/framework/blob/24d3207c4693d64dca08b892c609dec2b2d2e21b/src/Illuminate/Support/helpers.php#L462-L473
param mixed $value

https://github.com/laravel/framework/blob/24d3207c4693d64dca08b892c609dec2b2d2e21b/src/Illuminate/Support/Collection.php#L62-L71
param mixed $items

https://github.com/laravel/framework/blob/24d3207c4693d64dca08b892c609dec2b2d2e21b/src/Illuminate/Support/Collection.php#L2113-L2136

  • param mixed $items
  • return array
    but returns string
$today = Carbon::now();
$resource = fopen('index.php', 'r');

$types = [
    '1',
    1,
    1.1,
    true,
    [1],
    (object)[],
    new \stdClass(),
    null,
    $resource,
    $today,
];

foreach ($types as $type) {
    dump(collect($type));
}

image

All 6 comments

That's the correct behavior. You need to provide an array:

$today = Carbon::now();
$collection = collect([$today]);
dd($collection);

That's the correct behavior.

Hmm I'd consider this a bug since the $items property is always supposed to contain an array (as defined in the Collection class itself).

https://github.com/laravel/framework/blob/24d3207c4693d64dca08b892c609dec2b2d2e21b/src/Illuminate/Support/Collection.php#L44-L49

In this instance, the $items property is being set to a string, which would break other collection methods.

That's the correct behavior.

Put differently: You aren't using collect() correctly. If you provide a single value that shouldn't be converted to an array, you need to wrap it in an array.

@staudenmeir why are you so sure?
https://github.com/laravel/framework/blob/24d3207c4693d64dca08b892c609dec2b2d2e21b/src/Illuminate/Support/helpers.php#L462-L473
param mixed $value

https://github.com/laravel/framework/blob/24d3207c4693d64dca08b892c609dec2b2d2e21b/src/Illuminate/Support/Collection.php#L62-L71
param mixed $items

https://github.com/laravel/framework/blob/24d3207c4693d64dca08b892c609dec2b2d2e21b/src/Illuminate/Support/Collection.php#L2113-L2136

  • param mixed $items
  • return array
    but returns string
$today = Carbon::now();
$resource = fopen('index.php', 'r');

$types = [
    '1',
    1,
    1.1,
    true,
    [1],
    (object)[],
    new \stdClass(),
    null,
    $resource,
    $today,
];

foreach ($types as $type) {
    dump(collect($type));
}

image

Sorry, the whole time I thought you were expecting a collection with a single Carbon instance. I just saw that you are expecting a collection with a single serialized Carbon instance (i.e. a string).

Then I agree that this is a bug. jsonSerialize() doesn't have to return an array. I'll submit a fix.

Thank you!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

RomainSauvaire picture RomainSauvaire  路  3Comments

PhiloNL picture PhiloNL  路  3Comments

klimentLambevski picture klimentLambevski  路  3Comments

JamborJan picture JamborJan  路  3Comments

CupOfTea696 picture CupOfTea696  路  3Comments