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