【问题标题】:Laravel dd function limitationsLaravel dd 功能限制
【发布时间】:2016-12-24 23:22:17
【问题描述】:

我有一个包含 320 个数组的数组,而常规的 var_dump 向我展示了包含所有嵌套元素的 320 个元素,Laravel 的 dd 助手截断索引 147 处的嵌套元素以及所有其他元素被截断,没有扩展它们的选项,请参见下面的示例

  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]

为什么限制为 147 条完整记录以及如何提高限​​制? 相关主题Is Laravels' DD helper function working properly? 实际上并没有解释限制。

这是相当一致的行为,我在 Laravel 5.2 和 php7 上测试过

  • Linux(Laravel Forge、DO droplet、Ubuntu)
  • Mac(Laravel 代客)
  • Windows (valet4windows)

在元素 #147 上的每个地方都得到了完全相同的剪辑。使用 CLI php artisan tinker 输出相同的剪辑

...
"name" => "dccode"   ]   147 => array:17 [
"total_unconfirmed_subscribers" => 0
 16   ]   148 => array:17 [ 17]
...

【问题讨论】:

  • 你有没有想过用print_r()来代替?
  • var_dumpprint_r 都可以,看数据不是我的问题,我想了解 dd 限制。
  • 你使用的是哪个 laravel 版本? 4.2 和 5.2 甚至都返回 20.000 个元素。
  • 5.2 甚至不到 20k
  • 这很奇怪。我昨天试过了,甚至复制了你的可见数组,创建了一个 for 循环,以便我得到 20.000 个条目,然后用 dd 转储它。它在 4.2 和 5.2 中都有效。你试过用另一个数组吗?您也可以尝试在 CLI 中运行它。 Laravel 使用 CLIDumper 比。

标签: php laravel debugging


【解决方案1】:

在 5.0 版本之前,laravel 的 dd() 函数如下所示:

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

从 5.0 开始看起来像这样:

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

    die(1);
}

Dumper 正在使用 symfony 的 VarCloner,它扩展了 AbstractCloner。此类有一个$maxItems 属性设置为 2500。请参阅:https://github.com/symfony/var-dumper/blob/master/Cloner/AbstractCloner.php#L125

每个数组有 17 个项目。将它乘以 147 得到 2499。这就是为什么键 147 处的数组在第一项之后被截断的原因。

如果你想增加你需要覆盖 laravel 的 Dumper 类(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);
    }
}

【讨论】:

  • 这确实有效!很好的解释,谢谢,您能推荐一种更好的方法来覆盖我的自定义应用程序中的dump 函数而不影响任何供应商代码吗?
  • 是的,显然将其直接写入核心类是个坏主意。这只是一个提示,以便您知道如何增加限制。现在或多或少取决于你。一种简单的方法是编写自己的 dd 函数。这很容易,因为 laravel 正在检查函数是否已经存在:stackoverflow.com/a/28475973/1233206 - 或者你需要创建一个自定义的 Dumper 来扩展 laravel 的 Dumper。这就是我所说的“覆盖”:)
  • 是的,最终得到了自定义AppDumper 类和我的dd,它在我的助手require __DIR__.'/../app/helpers.php'; 中使用它在主要自动加载之前的boostrap/autoload.php
【解决方案2】:

我的建议是在引导文件夹中创建一个自定义帮助文件

1) 按照以下答案为您的 Laravel 应用程序创建自定义辅助函数,如果太复杂,您可以跳过以下步骤,将步骤 2 中的我的函数用作任何普通函数并简单地调用它>> https://stackoverflow.com/a/28290359/10539212

2) 我想给这个家伙一些功劳,我按照他的指南创建我自己的 ddd 函数 >> 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 = 无限制(这种方式很容易自定义)

所以,现在当你使用这个 ddd 函数时,你可以得到正常 dd 函数的完整输出。我认为这种方法比覆盖任何现有功能要好。但请注意,由于现在将完全显示具有任意深度的变量,因此您可能会遇到更长的加载时间。希望对您有所帮助。

【讨论】:

    【解决方案3】:

    我的建议是你在 VarDumper 组件中添加一个 handler

    在您的 AppServiceProvider.php 中:

    (在class 声明之前)

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

    (在boot() 方法内)

    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));
    });
    

    根据Symfony's VarDumper component documentation

    setMaxItems() 配置将被克隆到最小嵌套深度的最大项目数。项目使用 a 计数 广度优先算法,使较低级别的项目具有较高的优先级 比深度嵌套的项目。指定 -1 会移除限制。

    在文档中,您可以看到自定义克隆器、转储器和脚轮组件的其他方法。

    【讨论】:

      猜你喜欢
      • 2017-05-30
      • 2014-12-27
      • 1970-01-01
      • 2010-09-13
      • 2017-08-30
      • 1970-01-01
      • 2013-08-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多