【问题标题】:How can I capture the result of var_dump to a string?如何将 var_dump 的结果捕获到字符串?
【发布时间】:2010-09-13 11:02:05
【问题描述】:

我想将var_dump 的输出捕获到一个字符串中。

PHP 文档说;

与将结果直接输出到浏览器的任何东西一样,output-control functions 可用于捕获此函数的输出,并将其保存在字符串中(例如)。

有什么例子可以说明它是如何工作的?

print_r() 不是一个有效的可能性,因为它不会给我所需的信息。

【问题讨论】:

    标签: php string var-dump


    【解决方案1】:

    使用输出缓冲:

    <?php
    ob_start();
    var_dump($someVar);
    $result = ob_get_clean();
    ?>
    

    【讨论】:

    • 使用输出缓冲很可能会对性能产生负面影响。如果您需要在执行复杂脚本期间查看多个变量,它也会变得非常混乱。
    • @Inwdr 我只使用过 var_dump 作为调试的便利功能,并且肯定从未在生产代码中留下 var_dump 语句。我想这是典型的。在这种情况下,性能不太可能完全相关。
    • 这是对这个问题的一个很好的字面答案,因为您正在“捕获 [ing] var_dump 到字符串的结果”,就像所问的那样。 var_export() 在精神上是一个更好的答案,因为它通常更有意义。
    • @AlbertHendriks 我更喜欢 var_dump。启用 Xdebug 后,您将获得漂亮的数据显示。
    • 这是完美的答案。 var_export 答案冗长且无关紧要,因为它既不使用 var_dump 也不使用输出捕获,而且 var_exportprint_r 一样,不提供类型。
    【解决方案2】:

    你也可以这样做:

    $dump = print_r($variable, true);
    

    【讨论】:

    • 我确实特别提到了 var_dump :)
    • 我个人更喜欢尽可能使用print_r,但不幸的是,有时它不能提供足够的信息。例如,由于它可以转换为字符串,falsenull 都显示为空字符串。如果我关心这些之间的区别,我会不情愿地求助于var_dumpvar_export
    【解决方案3】:

    试试var_export

    您可能想查看 var_export — 虽然它没有提供与 var_dump 相同的输出,但它提供了第二个 $return 参数,这将导致它返回其输出而不是打印它:

    $debug = var_export($my_var, true);
    

    为什么?

    比起使用ob_startob_get_clean(),我更喜欢这种单行方式。我还发现输出更容易阅读,因为它只是 PHP 代码。

    var_dumpvar_export 之间的区别在于var_export 返回一个“变量的可解析字符串表示”,而var_dump 只是转储有关变量的信息。这在实践中意味着var_export 为您提供了有效的PHP 代码(但可能不会为您提供关于变量的那么多信息,尤其是在您使用resources 时)。

    演示:

    $demo = array(
        "bool" => false,
        "int" => 1,
        "float" => 3.14,
        "string" => "hello world",
        "array" => array(),
        "object" => new stdClass(),
        "resource" => tmpfile(),
        "null" => null,
    );
    
    // var_export -- nice, one-liner
    $debug_export = var_export($demo, true);
    
    // var_dump
    ob_start();
    var_dump($demo);
    $debug_dump = ob_get_clean();
    
    // print_r -- included for completeness, though not recommended
    $debug_printr = print_r($demo, true);
    

    输出的区别:

    var_export(上例中为$debug_export):

     array (
      'bool' => false,
      'int' => 1,
      'float' => 3.1400000000000001,
      'string' => 'hello world',
      'array' => 
      array (
      ),
      'object' => 
      stdClass::__set_state(array(
      )),
      'resource' => NULL, // Note that this resource pointer is now NULL
      'null' => NULL,
    )
    

    var_dump(上例中为$debug_dump):

     array(8) {
      ["bool"]=>
      bool(false)
      ["int"]=>
      int(1)
      ["float"]=>
      float(3.14)
      ["string"]=>
      string(11) "hello world"
      ["array"]=>
      array(0) {
      }
      ["object"]=>
      object(stdClass)#1 (0) {
      }
      ["resource"]=>
      resource(4) of type (stream)
      ["null"]=>
      NULL
    }
    

    print_r(上例中的$debug_printr):

    Array
    (
        [bool] => 
        [int] => 1
        [float] => 3.14
        [string] => hello world
        [array] => Array
            (
            )
    
        [object] => stdClass Object
            (
            )
    
        [resource] => Resource id #4
        [null] => 
    )
    

    警告:var_export 不处理循环引用

    如果您尝试使用循环引用转储变量,调用 var_export 将导致 PHP 警告:

     $circular = array();
     $circular['self'] =& $circular;
     var_export($circular);
    

    结果:

     Warning: var_export does not handle circular references in example.php on line 3
     array (
       'self' => 
       array (
         'self' => NULL,
       ),
     )
    

    另一方面,var_dumpprint_r 在遇到循环引用时都会输出字符串*RECURSION*

    【讨论】:

    • 这绝对是比公认的更好的答案。我很惊讶它没有更多的赞成票!您能否详细说明为什么它可能无法提供他正在寻找的所有信息?
    • @JMTyler var_export 返回一个 parsable 字符串——本质上是 PHP 代码——而 var_dump 提供数据的原始转储。因此,例如,如果您在值为 1 的整数上调用 var_dump,它将打印出int(1),而 var_export 只会打印出1
    • var_export 如果在 var_dump 工作时将它与 $GLOBALS 一起使用,它就会落地。
    • 不适用于包含对自身的引用的变量。var_export 不像 var_dump 那样工作;像这样,$v=[];$v[]=&$v;var_export($v,true); ...
    • 停止炒作人。 var_export 实际上并不适合调试,因为您无法在浏览器中搜索 (int) 或 (string)` 等。它还会将大量信息混入一个小空间中,只需尝试:var_export(''); var_export('\'');。最重要的是,为 PHP 致命错误做好准备: Nesting level too deep - recursive dependency? in C:\path\file.php on line 75
    【解决方案4】:

    您也可以尝试使用serialize() 函数。有时它对于调试目的非常有用。

    【讨论】:

    • 一句警告 - 如果您希望将输出作为字符串的原因是 error_log 它,则不应使用此解决方案,因为序列化的输出可能包含空字节和 error_log @987654322 @.
    【解决方案5】:

    如果您想在运行时查看变量的内容,请考虑使用真正的调试器,例如 XDebug。这样您就不需要弄乱源代码,即使普通用户访问您的应用程序,您也可以使用调试器。他们不会注意到的。

    【讨论】:

      【解决方案6】:

      另外echo json_encode($dataobject); 可能会有所帮助

      【讨论】:

      • 在我看来,在这种情况下,输出非常混乱,与调试目的相去甚远。
      • Mark Biek 没有说任何关于调试的事情,是吗?也许他只需要保存在数据库中的对象。在这种情况下,我提供的方法会很好用。无论如何,感谢您的提醒,Tomáš Zato。
      • 无论如何,json_encode 不会包含var_dump 所做的所有数据(例如变量类型)。 json_encode 输出与print_R 相同的信息,只是格式不同。
      • 好的,我会再解释一次。 OT 表示他需要var_dump 的输出。他还表示print_R 提供的信息不足以满足他的需求。 json_encodeprint_r 提供的信息没有真正的区别——只是数据格式不同。鉴于此,如果print_r 不够用,json_encode 也不够用。请不要再抱怨否决票了。这显然不仅仅是随机点击,所以处理它。
      【解决方案7】:

      下面是作为函数的完整解决方案:

      function varDumpToString ($var)
      {
          ob_start();
          var_dump($var);
          return ob_get_clean();
      }
      

      【讨论】:

      • 不能使用超过 1 个变量... var_dump("foo","bar") => string(3) "foo" string(3) "bar" varDumpToString("foo ","bar") => 字符串(3) "foo"
      【解决方案8】:

      如果您使用的是 PHP>=7.0.0

      function return_var_dump(...$args): string
      {
          ob_start();
          try {
              var_dump(...$args);
              return ob_get_clean();
          } catch (\Throwable $ex) {
              // PHP8 ArgumentCountError for 0 arguments, probably..
              // in php<8 this was just a warning
              ob_end_clean();
              throw $ex;
          }
      }
      

      或者如果您使用的是 PHP >=5.3.0:

      function return_var_dump(){
          ob_start();
          call_user_func_array('var_dump', func_get_args());
          return ob_get_clean();
      }
      

      或者如果你使用的是 PHP

      function return_var_dump(){
          $args = func_get_args(); // For <5.3.0 support ...
          ob_start();
          call_user_func_array('var_dump', $args);
          return ob_get_clean();
      }
      

      (在 5.3.0 之前,如果直接将 func_get_args 用作另一个函数调用的参数,则存在一个错误,因此您必须将其放入变量中并使用该变量,而不是直接将其用作参数.. )

      【讨论】:

      • @MarkAmery 似乎是真的。我只是让它变得简单。
      • PHP5.6+ function vardump(...$args){if(count($args)){ob_start();var_dump(...$args);return ob_get_clean();}return '';}
      • @a55 更像function vardump(...$args){if(count($args)){ob_start();var_dump(...$args);return ob_get_clean();}else{trigger_error("vardump() expects at least 1 parameter, 0 given.",E_USER_ERROR);return "";}} - 对于 PHP=8 它会抛出一个 ArgumentCountError 异常,所以你的 vardump() 也应该在 php>=8..
      【解决方案9】:

      From the PHP manual:

      此函数显示有关一个或多个表达式的结构化信息,包括其类型和值。

      所以,这里是 PHP 的 var_dump()real 返回版本,它实际上接受一个可变长度的参数列表:

      function var_dump_str()
      {
          $argc = func_num_args();
          $argv = func_get_args();
      
          if ($argc > 0) {
              ob_start();
              call_user_func_array('var_dump', $argv);
              $result = ob_get_contents();
              ob_end_clean();
              return $result;
          }
      
          return '';
      }
      

      【讨论】:

      • +1 用于为实际问题提供真实答案。我正在阅读这篇文章,因为我需要 var_dump,而不是 var_export、print_r、serialize、json_encode 或真正的调试器。我也知道如何使用它们。 OP 要求 var_dump,我需要 var_dump。谢谢!
      • 如果你想对 var_dump 保持真实,你必须 trigger_error("Wrong parameter count for var_dump_str()");当 argc
      • 这几乎没有添加任何已被接受的答案。正如@hanshenrik 所指出的,这里的$argc 检查是不必要的,并且可以说是不正确的,一旦你把它拿走,你真正添加的就是call_user_func_arrayfunc_get_args 调用。
      【解决方案10】:

      来自http://htmlexplorer.com/2015/01/assign-output-var_dump-print_r-php-variable.html

      var_dump 和 print_r 函数只能直接输出到浏览器。所以这些函数的输出只能通过php的输出控制函数来获取。下面的方法可能有助于保存输出。

      function assignVarDumpValueToString($object) {
          ob_start();
          var_dump($object);
          $result = ob_get_clean();
          return $result;
      }
      

      ob_get_clean() 只能清除最后输入到内部缓冲区的数据。所以 如果您有多个条目,ob_get_contents 方法将很有用。

      来自与上述相同的来源:

      function varDumpToErrorLog( $var=null ){
          ob_start();                    // start reading the internal buffer
          var_dump( $var);          
          $grabbed_information = ob_get_contents(); // assigning the internal buffer contents to variable
          ob_end_clean();                // clearing the internal buffer.
          error_log( $grabbed_information);        // saving the information to error_log
      }
      

      【讨论】:

      • 当您引用其他来源的材料时,请正确注明。在我即将进行编辑之前,此答案中唯一被格式化为引用的部分是您没有从某人的博客中复制和粘贴的部分。
      【解决方案11】:

      这可能有点跑题了。

      我正在寻找一种将此类信息写入我的 PHP-FPM 容器的 Docker 日志的方法,并想出了下面的 sn-p。我确信这可以被 Docker PHP-FPM 用户使用。

      fwrite(fopen('php://stdout', 'w'), var_export($object, true));
      

      【讨论】:

      • 句柄永远不会关闭,所以这是资源泄漏,这可能是长时间运行的守护程序样式脚本中的问题。但试试file_put_contents('php://stdout',var_export($object, true),FILE_APPEND);
      【解决方案12】:

      我真的很喜欢var_dump() 的详细输出,但对var_export()print_r() 的输出不满意,因为它没有提供太多信息(例如缺少数据类型、缺少长度)。

      为了编写安全且可预测的代码,有时区分空字符串和空字符串很有用。或介于 1 和真之间。或者介于 null 和 false 之间。所以我想要我的数据类型在输出中。

      虽然有帮助,但我没有在现有响应中找到一个干净简单的解决方案,将var_dump() 的彩色输出转换为人类可读的输出,不带 html 标签并包含来自@987654325 的所有详细信息@。

      注意,如果你有一个彩色的var_dump(),这意味着你安装了Xdebug,它会覆盖php的默认var_dump()来添加html颜色。

      出于这个原因,我创建了这个细微的变化,给出了我所需要的:

      function dbg_var_dump($var)
          {
              ob_start();
              var_dump($var);
              $result = ob_get_clean();
              return strip_tags(strtr($result, ['=&gt;' => '=>']));
          }
      

      返回以下漂亮的字符串:

      array (size=6)
        'functioncall' => string 'add-time-property' (length=17)
        'listingid' => string '57' (length=2)
        'weekday' => string '0' (length=1)
        'starttime' => string '00:00' (length=5)
        'endtime' => string '00:00' (length=5)
        'price' => string '' (length=0)
      

      希望它可以帮助某人。

      【讨论】:

      • 2021年,对于调试应用程序错误日志,这是IMO最有用的答案。
      【解决方案13】:

      长字符串:只需使用echo($var); 而不是dump($var);

      对象数组var_dump('&lt;pre&gt;'.json_encode($var).'&lt;/pre&gt;);'

      【讨论】:

        猜你喜欢
        • 2013-02-05
        • 1970-01-01
        • 2012-12-08
        • 2015-03-05
        • 1970-01-01
        • 2014-03-26
        • 2017-11-21
        • 1970-01-01
        • 2011-11-04
        相关资源
        最近更新 更多