2013-06-21 77 views
10
Warning: json_encode(): recursion detected in [Directory] 

什么是这个错误,我似乎无法解决问题。它正在产生每个错误500面临的大BIG日志。大小为133,000,000字节。这是垃圾邮件的日志,直到内存最大。json_encode给出递归错误

<?php 
include('simple_html_dom.php'); 

if(isset($_REQUEST['type']) && $_REQUEST['type'] = "getmoredetails"){ 
retrievemore($_REQUEST['htmlsource']); 
} 

function retrievemore($htmlcode){ 
$retrievetitle = retrievechTitle($htmlcode); 
$retrievermb = retrievechRMB($htmlcode); 
echo json_encode(array("error"=>0,"rmb"=>$retrievermb,"title"=>$retrievetitle)); 
} 
function retrievechTitle($htmlcode){ 
$html = str_get_html($htmlcode); 
$title = $html->find('div[class=tb-detail-hd]h3'); 
return $title[0]; 
} 
function retrievechRMB($htmlcode){ 
$html = str_get_html($htmlcode); 
$rmb = $html->find('[class=tb-rmb-num]'); 
return $rmb[0]; 
} 

?> 

我试图从HTML文件中提取数据,其他提取工作正常,除了上述,给出了很多问题。我甚至将这组代码专门分成一个PHP文件进行处理和相同的问题。

有什么想法?我在主页上使用带有多个函数的jQuery Ajax $.ajax({
我是新来的Ajax,在一个页面中有多个Ajax是正确的吗?

+0

可以粘贴在'simple_html_dom.php' – user20232359723568423357842364

+0

它太大了上传代码,它将垃圾邮件的问题空间。无论如何,这是在sourceforge简单的HTML解析器的默认文件 – CodeGuru

回答

9

清楚的问题在于你试图调用的东西不适合它json_encode

echo json_encode(array("error"=>0,"rmb"=>$retrievermb,"title"=>$retrievetitle)); 

什么,我们可能会问,是$retrievetitle?它有什么样的价值?那么,我们可以在函数定义中找到它:

$html = str_get_html($htmlcode); 
$title = $html->find('div[class=tb-detail-hd]h3'); 
return $title[0]; 

很明显它是某种对象。我对simple_html_dom库不熟悉,但可能它是属于该库的对象,并表示一个HTML元素。也许这是一个本地DOMElement对象;我不知道。

但是,明确的是它是某种递归结构。这就是说,从某种意义上说,它包含了它自身。这在PHP中是完全可能的,但不可能用JSON字符串表示。例如,在PHP:

class Foo { 
    public $self; 

    public function __construct() { 
     $this->self = $this; 
    } 
} 
$foo = new Foo; 

$foo->self是相同的对象$foo。事实上,你可以做$foo->self->self->self,它会正常工作。这是一个非常简单的递归结构。你的情况可能会更复杂一些,但原则上并不相同。这不能用JSON表示。 json_encode遇到递归时会出错。

我想你可能想存储标题的文本内容,而不是标题元素本身。简单阅读API documentation for the library,似乎你想要plaintext属性。我不太清楚这是如何工作的(API方面是,我们应该说,稀疏的),但我的猜测是以下几点:

return $title[0]->plaintext; 

不过,这只是一个猜测。

+0

嗨, - >明文确实删除错误,我想我知道你的意思。谢谢 – CodeGuru

+0

让我继续阅读它来尝试理解它:x谢谢你这么寂寞。谢谢。 – CodeGuru

+0

很高兴有帮助。 – lonesomeday

1

简单的例子来重新创建问题

<?php 
$o = new StdClass; 
$o->arr = array(); 
$o->arr[] = $o; 

json_encode($o); 

一旦json_encode()遇到$邻>改编[0] == $·其必须与$Ø重新开始,达到$邻> arr [0],再次从$ o开始,等等。为了防止这种情况,函数“记住”它已经处理的每个节点。如果它再次“看到”同一个节点,它会抛出递归警告。
您从函数返回的simple_html_dom对象可能会引用父对象或类似的东西,导致递归。
因此,也许return (string)$title[0];return (string)$rmb[0];将解决这个问题。

1

你想完成什么,使用POST方法发送HTML源代码。然后解析它在服务器端有点过分杀死。

<?php 
include('simple_html_dom.php'); 

if(isset($_REQUEST['type']) && $_REQUEST['type'] = "getmoredetails"){ 
    >> echo $_REQUEST['htmlsource']; 
    >> return; 
    retrievemore($_REQUEST['htmlsource']); 
} 

function retrievemore($htmlcode){ 
    $retrievetitle = retrievechTitle($htmlcode); 
    $retrievermb = retrievechRMB($htmlcode); 
    >> gettype($retrievetitle) . ' – ' . gettype($retrievermb); 
    >> return; 
    echo json_encode(array("error"=>0,"rmb"=>$retrievermb,"title"=>$retrievetitle)); 
} 

function retrievechTitle($htmlcode){ 
    $html = str_get_html($htmlcode); 
    $title = $html->find('div[class=tb-detail-hd]h3'); 
    return $title[0]; 
} 
function retrievechRMB($htmlcode){ 
    $html = str_get_html($htmlcode); 
    $rmb = $html->find('[class=tb-rmb-num]'); 
    return $rmb[0]; 
} 

?> 

你的AJAX调用是什么样的?你是否将类型参数设置为“POST”?

$.ajax({ 
    type: "POST", 
    url: "/echo/json/", 
    data: { name: "John", location: "Boston" } 
}).done(function(json) 
    console.log(json); 
}); 

你也应该尝试只调用json_encode()函数本身。看看你是否有错误。

echo json_encode(array("error"=>0,"rmb"=>"rmb","title"=>"title")); 
+0

嗨,是的,Ajax和是使用POST。寂寞天有一个很好的解释,如上所述。固定。感谢您的帮助。尽管如此,欢迎来到STACKOVERFLOW! – CodeGuru

1

有时,simple_html_dom.php不会像预期的那样转换为字符串。 我已经投字符串语法解决的问题:

$HTML_DOM = new simple_html_dom(); 
$HTML_DOM->load($HTML_Template,true,false); // Preserve line breaks 
$Content_Box_Data = $HTML_DOM->find('div.Content_Box_Data',0); // find() 
$Content_Box_Data->innertext = "Some Content"; 
$HTML_Template = (string)$HTML_DOM;