15

I have an array of 320 arrays, while regular var_dump shows me exactly 320 elements with all nested elements, Laravel's dd helper truncates the nested element at index 147 and all the further elements are truncated with no option to expand them, see the example below

  146 => array:17 [▼
    "total_unconfirmed_subscribers" => 0
    "total_subscribers_subscribed_yesterday" => 0
    "unique_list_id" => "24324"
    "http_etag" => ""fbb6febfca8af5541541ea960aaedb""
    "web_form_split_tests_collection_link" => "https://api.com/1.0/"
    "subscribers_collection_link" => "https://api.com/1.0/"
    "total_subscribers_subscribed_today" => 0
    "id" => 23432
    "total_subscribed_subscribers" => 0
    "total_unsubscribed_subscribers" => 0
    "campaigns_collection_link" => "https://api.com/1.0/"
    "custom_fields_collection_link" => "https://api.com/1.0/accounts"
    "self_link" => "https://api.com/1.0/accounts"
    "total_subscribers" => 0
    "resource_type_link" => "https://api.com/1.0/#list"
    "web_forms_collection_link" => "https://api.com/"
    "name" => "dccode"
  ]
  147 => array:17 [▼
    "total_unconfirmed_subscribers" => 0
     …16
  ]
  148 => array:17 [ …17]
  149 => array:17 [ …17]

Why is it limited to 147 full records and how to increase the limit? The related topic Is Laravels' DD helper function working properly? doesn't actually explain the limits.

This is pretty consistent behavior, I've tested with Laravel 5.2 and php7 on

  • Linux (Laravel Forge, DO droplet, Ubuntu)
  • Mac (Laravel Valet)
  • Windows (valet4windows)

Everywhere got exactly the same cut on element #147. Using CLI php artisan tinker outputs the same cut

...
"name" => "dccode"   ]   147 => array:17 [
"total_unconfirmed_subscribers" => 0
 16   ]   148 => array:17 [ 17]
...
Community
  • 1
  • 1
vitr
  • 6,766
  • 8
  • 30
  • 50
  • Have you thought about using `print_r()` instead? – Derek Pollard Aug 18 '16 at 06:27
  • both `var_dump` and `print_r` work OK, It's not my problem to see the data, I want to understand dd limits. – vitr Aug 18 '16 at 06:29
  • Which laravel version are you using? Both 4.2 and 5.2 are even returning 20.000 elements. – sleepless Aug 19 '16 at 21:41
  • 5.2 and not even close to 20k – vitr Aug 19 '16 at 23:41
  • That's pretty strange. I tried it yesterday and even copied your visible array, created a for loop so that I got 20.000 entries and then dumped it with dd. It worked both in 4.2 and 5.2. Have you tried it with another array? You can also try to run it in CLI. Laravel uses the CLIDumper than. – sleepless Aug 20 '16 at 11:18
  • @sleepless kk, can you tell your server config, os, php versions, etc.? I've tested so far with php 7, on laravel forge DO instance ( linux covered), on my pc with valet4windows also php 7 (windows covered), will try on mac soon, but I'm sure I'll get the same cut on 147 records. In CLI mode got exactly the same cut ` 147 => array:17 [ "total_unconfirmed_subscribers" => 0 ÔǪ16 ]` – vitr Aug 20 '16 at 11:48
  • @vitr: Sorry! I got you wrong. Please look at my answer. – sleepless Aug 20 '16 at 12:32

4 Answers4

29

Prior to version 5.0 laravel's dd() function looked as follows:

function dd()
{
    array_map(function($x) { var_dump($x); }, func_get_args()); die;
}

Since 5.0 it looks like this:

function dd()
{
    array_map(function ($x) {
        (new Dumper)->dump($x);
    }, func_get_args());

    die(1);
}

The Dumper is using symfony's VarCloner which is extending the AbstractCloner. This class has a $maxItems attribute set to 2500. See: https://github.com/symfony/var-dumper/blob/master/Cloner/AbstractCloner.php#L125

You have 17 items per array. Multiply it by 147 and you get 2499. That's why your array at key 147 is truncated after it's first item.

If you'd like to increase that you'd need to override laravel's Dumper class (https://github.com/laravel/framework/blob/5.2/src/Illuminate/Support/Debug/Dumper.php):

public function dump($value)
{
    if (class_exists(CliDumper::class)) {
        $dumper = 'cli' === PHP_SAPI ? new CliDumper : new HtmlDumper;

        $cloner = new VarCloner();
        $cloner->setMaxItems(5000);
        $dumper->dump($cloner->cloneVar($value));
    } else {
        var_dump($value);
    }
}
sleepless
  • 1,769
  • 1
  • 22
  • 33
  • this actually works! great explanation, thanks, would you recommend a better way to override `dump` function in my custom app without affecting any vendor code? – vitr Aug 20 '16 at 12:44
  • 1
    Yes, clearly it's a bad idea to write it directly to the core class. That was just a hint so that you know how to increase the limit. It's now more or less up to you. An easy way would be to write your own dd-function. This is quite easy since laravel is checking if the function already exists: http://stackoverflow.com/a/28475973/1233206 - alternatively you'd need to create a custom Dumper which is extending laravel's Dumper. That's what I meant with "overriding" :) – sleepless Aug 20 '16 at 12:55
  • yeah, ended up with custom `AppDumper` class and with my `dd` which uses it in my helpers `require __DIR__.'/../app/helpers.php';` in `boostrap/autoload.php` before main autoload – vitr Aug 20 '16 at 13:35
9

My suggestion is you add a handler in the VarDumper component.

In your AppServiceProvider.php:

(before class declaration)

use Symfony\Component\VarDumper\VarDumper;
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\CliDumper;
use Symfony\Component\VarDumper\Dumper\HtmlDumper;

(inside boot() method)

VarDumper::setHandler(function ($var) {
    $cloner = new VarCloner();
    $cloner->setMaxItems(-1); // Specifying -1 removes the limit
    $dumper = 'cli' === PHP_SAPI ? new CliDumper() : new HtmlDumper();

    $dumper->dump($cloner->cloneVar($var));
});

According to Symfony's VarDumper component documentation:

setMaxItems() Configures the maximum number of items that will be cloned past the minimum nesting depth. Items are counted using a breadth-first algorithm so that lower level items have higher priority than deeply nested items. Specifying -1 removes the limit.

And in the documentation you can see other methods for customizing the Cloners, Dumpers and Casters components.

Lucas Martins
  • 508
  • 6
  • 9
7

My suggestions for you is to create a custom helpers file in bootstrap folder

1) follows the following answer to create a custom helper function for your Laravel application, if it is too complicated, you can skip the following step, use my function in step 2 as any normal function and simply call it >> https://stackoverflow.com/a/28290359/10539212

2) I would like to give some credits to this guy, I follow his guide to create my own ddd function >> https://tighten.co/blog/a-better-dd-for-your-tdd

use Illuminate\Support\Debug\HtmlDumper;
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\CliDumper;

function ddd()
{
    $args = func_get_args();
    $defaultStringLength = -1;
    $defaultItemNumber = -1;
    $defaultDepth = -1;

    foreach ($args as $variable) {
        $dumper = 'cli' === PHP_SAPI ? new CliDumper() : new HtmlDumper();

        $cloner = new VarCloner();
        $cloner->setMaxString($defaultStringLength);
        $cloner->setMaxItems($defaultItemNumber);

        $dumper->dump($cloner->cloneVar($variable)->withMaxDepth($defaultDepth));
    }

    die(1);
}

-1 = no limit (easy to customize in this way)

So, now when you use this ddd function, you can get the complete output of normal dd function. I think this approach is better than overwriting any existing function. But be careful, since now variables with any number of depth will be displayed completely, you may experience longer loading time. Hope it helps.

Phantom1412
  • 319
  • 4
  • 9
0

Laravel's dd() function is used to print/dump some value in browser and then stop the execution(skip all other code given after the dd())


Alternate of dd() function.

There are two options.

  1. If you want to print single value in browser and then stop the execution.

    echo $your_value;

    exit();

  2. If you want to print some array values in browser and then stop the execution.

    print_r($your_array);

    exit();

Billu
  • 2,733
  • 26
  • 47