为什么 var_dump 一个 Doctrine 对象会导致 Apache 崩溃?

8

我有一个非常奇怪的问题,当我尝试使用var_dump(或print_r)打印Doctrine对象时,我的Apache会返回一个空白页面(200 OK header)。我可以使用var_dump打印普通的php变量,例如:

$dummy = array("a" => 1, "b" =>2);

这段代码可以正常工作。但是我无法处理任何Doctrine类的对象(例如从$connection->query()获取的结果,或来自我的Doctrine对象模型实例的类)。

有人知道为什么会发生这种情况吗?


4
这是“doctrine var_dump”在谷歌上的排名第一结果。请您接受正确答案(https://dev59.com/3kXRa4cB1Zd3GeqPsouE#8646048),而不是“增加内存限制”那个,因为它并不能真正解决问题。 - rjmunro
4个回答

51

延迟加载代理始终包含一个Doctrine的EntityManager实例和其所有依赖项。

因此,var_dump可能会导致非常大的递归结构的输出,无法渲染和阅读。您必须使用\Doctrine\Common\Util\Debug::dump()来限制输出为可读的级别。请注意,此函数的默认深度设置为2(它是第二个参数)。


除了增加内存限制之外,解决这个问题的方法是使用xdebug,并利用它的xdebug.var_display_max_depth仅转储所有递归的一定深度。 - ficuscr

9
使用Doctrine_Record类的toArray方法。
var_dump($doctrine_record->toArray());

只显示数据库字段,避免倾倒完整的Doctrine内部(其中包含自引用/递归)


1

有时候我尝试使用print_r()打印一个自引用对象时会出现这种情况——它进入了一个循环并耗尽了内存。可能这就是你遇到的问题。

尝试增加内存限制(ini_set('memory_limit', '256M');),看看是否可以解决问题。

编辑:我认为这个问题没有实际的解决方法——PHP内部的var_dump/print_r在递归深度上没有限制(或者至少没有正确地限制)。如果安装XDebug扩展,它可以用一个更好的版本替换内置的var_dump,处理递归更好。


11
不过,你不会得到有用的输出,因此最好使用Doctrine dump \Doctrine\Common\Util\Debug::dump()函数,该函数在另一个答案中有描述。 - Gigala
2
增加内存限制永远不应该被视为一个好的答案。这就像推荐 chmod 777 一样。 - renoirb

0

如果您确定对象是Doctrine_Collection的实例,则可以使用toArray。 Xdebug无法帮助处理Doctrine记录。

我建议的方法是实现一个自定义递归函数来打印对象,需要时使用Doctrine_Record :: toArray()

function var_dump_improved()
{
   foreach (func_get_args() as $arg) {
       if ($args instanceof Doctrine_Collection) {
          print_r($arg);
       } else if ( $arg instanceof Traversable || is_array($arg) ) {
          // do a foreach and recall var_dump_improved on subelements
       } else if (...) {
          // other types
       } 
   }   
}

这里有一些递归函数,可以用于调试,最大嵌套级别如下

http://php.net/manual/en/function.var-dump.php

看看注释,找“递归”


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接