Php 使用带循环引用的print\u r和var\u dump

Php 使用带循环引用的print\u r和var\u dump,php,debugging,circular-reference,Php,Debugging,Circular Reference,我正在使用,似乎我想要调试的许多内置对象都有循环引用。这使得无法使用print_r()或var_dump()打印变量(因为它们无限跟随循环引用,或者直到进程内存耗尽,以先到者为准) 除了写我自己的print\rclone,还有更好的选择吗?我只希望能够将变量(对象、数组或标量)打印到日志文件、http头或网页本身 编辑:要澄清问题所在,请尝试以下代码: <?php class A { public $b; public $c; public function _

我正在使用,似乎我想要调试的许多内置对象都有循环引用。这使得无法使用
print_r()
var_dump()
打印变量(因为它们无限跟随循环引用,或者直到进程内存耗尽,以先到者为准)

除了写我自己的
print\r
clone,还有更好的选择吗?我只希望能够将变量(对象、数组或标量)打印到日志文件、http头或网页本身

编辑:要澄清问题所在,请尝试以下代码:

<?php

class A
{
    public $b;
    public $c;

    public function __construct()
    {
        $this->b = new B();
        $this->c = new C();
    }
}

class B
{
    public $a;

    public function __construct()
    {
        $this->a = new A();
    }
}

class C
{
}

ini_set('memory_limit', '128M');
set_time_limit(5);

print_r(new A());
#var_dump(new A());
#var_export(new A());

你可以用

var_export()不处理循环 参考资料,因为它将接近 无法生成可解析的PHP 代码。如果你想做 有充分代表性的东西 对于数组或对象,使用 序列化()。


更新:似乎我错了。我以为我不久前使用这个函数是为了这个目的,但它一定是某种醉酒的想象

这样,我能给出的唯一建议就是安装

输出:

Test Object
(
    [obj] => Test Object
 *RECURSION*
)

object(Test)[1]
  public 'obj' => 
    &object(Test)[1]
在我看来,
print\u r()
var\u dump()
都可以毫无问题地处理递归。在Windows上使用PHP5.3.5


var\u export()
未检测到递归,这会导致即时致命错误:

Fatal error:  Nesting level too deep - recursive dependency? in \sandbox\index.php on line 28

我们使用的是PRADO框架,它有一个名为“TVarDumper”的内置类,可以很好地处理如此复杂的对象——它甚至可以将其格式化为漂亮的HTML格式,包括语法高亮显示。您可以从中获取该类。

我也遇到了这个问题,我通过实现u get()方法来打破引用循环,从而解决了这个问题。在类声明中找不到属性后调用_get()方法。方法还获取缺少的属性的名称。使用它,您可以定义“虚拟属性”,它们的工作方式与普通属性相同,但print\r函数没有提到。这里有一个例子:

public function __get($name)
{
    if ($name=="echo") {
        return Zend_Registry::get('textConfig');
    }
}

具有相同的服务级别

用法示例:

<?php echo "<pre>"; \Doctrine\Common\Util\Debug::dump($result, 4); echo "</pre>";?>

TVarDumper旨在取代有缺陷的PHP函数
var_dump
print_r
,因为它可以正确识别复杂对象结构中的递归引用对象。它还具有递归深度控制,以避免某些特殊变量的不确定递归显示

检查:

XDebug变量转储 使用XDebug PHP扩展,它将检测并忽略循环引用,例如:

print_r(array_slice($desiredArray, 0, 4));
print\u r
+
array\u slice
根据这一点,您可以尝试:

/**
 * Export var function
 */
function features_var_export($var, $prefix = '', $init = TRUE, $count = 0) {
  if ($count > 50) {
    // Recursion depth reached.
    return '...';
  }

  if (is_object($var)) {
    $output = method_exists($var, 'export') ? $var->export() : features_var_export((array) $var, '', FALSE, $count+1);
  }
  else if (is_array($var)) {
    if (empty($var)) {
      $output = 'array()';
    }
    else {
      $output = "array(\n";
      foreach ($var as $key => $value) {
        // Using normal var_export on the key to ensure correct quoting.
        $output .= "  " . var_export($key, TRUE) . " => " . features_var_export($value, '  ', FALSE, $count+1) . ",\n";
      }
      $output .= ')';
    }
  }
  else if (is_bool($var)) {
    $output = $var ? 'TRUE' : 'FALSE';
  }
  else if (is_int($var)) {
    $output = intval($var);
  }
  else if (is_numeric($var)) {
    $floatval = floatval($var);
    if (is_string($var) && ((string) $floatval !== $var)) {
      // Do not convert a string to a number if the string
      // representation of that number is not identical to the
      // original value.
      $output = var_export($var, TRUE);
    }
    else {
      $output = $floatval;
    }
  }
  else if (is_string($var) && strpos($var, "\n") !== FALSE) {
    // Replace line breaks in strings with a token for replacement
    // at the very end. This protects whitespace in strings from
    // unintentional indentation.
    $var = str_replace("\n", "***BREAK***", $var);
    $output = var_export($var, TRUE);
  }
  else {
    $output = var_export($var, TRUE);
  }

  if ($prefix) {
    $output = str_replace("\n", "\n$prefix", $output);
  }

  if ($init) {
    $output = str_replace("***BREAK***", "\n", $output);
  }

  return $output;
}
特征变量导出 使用Drupal()模块中的以下函数:

用法:

echo serialize($object);
连载 使用
serialize
以序列化表示形式转储对象,例如:

echo json_encode($object);
JSON编码 使用
json\u encode
将其转换为json格式,例如:

print_r(json_decode(json_encode($value)));


另请参见:

这似乎为我完成了工作:

composer require symfony/var-dumper --dev

Symfony现在也有VarDumer组件:

它处理循环引用并支持远程转储服务器

安装非常简单:

<?php
/* ... */
dump($someVar);
然后您可以使用全局函数
dump
(我想已经包含了composer的autoload.php):


我不会使用
var\u export()
。我相信“不处理”的意思是“无法检测”或类似的东西。在PHP5.3.5上,
var_export()
导致
致命错误:嵌套级别太深-递归依赖?
。它不起作用:“致命错误:嵌套级别太深-递归依赖?”@binaryLV@Christian感谢您的澄清。这篇文章提供了一些见解,这与不同版本的php中执行对象的非严格比较方式有关“这一定是一些醉酒的想象”——我最近也遇到了一个糟糕的Ballmer高峰案例,兄弟。没有得到它。。。PHP 5.3.5在
B
的构造函数中抛出“致命错误:达到最大函数嵌套级别'100',正在中止!”,在该构造函数中创建新的
A
,从而创建新的
B
,再次创建新的
A
等。尝试创建新的
A
,而不在结果上使用
print\r()
,即。,使用
$obj=new A()
而不是
print\r(new A())
。您仍然会收到相同的错误吗?的可能重复项并不总是有效。我也面临同样的问题。由于循环错误,无法打印调试\u backtrace()对象reference@kervin,您使用哪个版本的PHP?如果知道“不总是”是什么时候,那就好了。对我来说,直到最近,印刷术还很管用。它只是为递归生成了递归。但从一段时间以来(PHP版本?),这似乎不再有效了。在Drupal中也能完美地工作!这个软件包已经被弃用了,取而代之的是。对我来说很有用,不是很整洁,但可以满足我的需要。谢谢
echo json_encode($object);
print_r(json_decode(json_encode($value)));
composer require symfony/var-dumper --dev
<?php
/* ... */
dump($someVar);