15
Warning:  json_encode(): recursion detected in [Directory] 

这是什么错误,我似乎无法解决问题。每个遇到的错误 500 都会生成一个 BIG BIG 日志。大小为 133,000,000 字节。它正在向日志发送垃圾邮件,直到内存最大。

<?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,对吗?

4

4 回答 4

13

问题显然在于您试图调用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遇到递归会报错。

我想您可能想要存储标题的文本内容,而不是标题元素本身。简要阅读library 的 API 文档,您似乎想要该plaintext属性。我不太确定这是如何工作的(我们可以说,API 是稀疏的),但我的猜测如下:

return $title[0]->plaintext;

但这只是一个有根据的猜测。

于 2013-06-21T12:57:42.560 回答
5

重新创建问题的简单示例

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

json_encode($o);

一旦 json_encode() 遇到 $o->arr[0]==$o 它将不得不从 $o 重新开始,到达 $o->arr[0],从 $o 重新开始,以此类推,无穷无尽。为了防止这种情况,该函数“记住”它已经处理过的每个节点。如果它再次“看到”同一个节点,它会抛出递归警告。
您从函数返回的 simple_html_dom 对象可能引用了它们的父对象或类似的东西,从而导致递归。
所以,也许 return (string)$title[0];并且return (string)$rmb[0];会解决这个问题。

于 2013-06-21T12:58:04.820 回答
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"));
于 2013-06-21T13:29:13.150 回答
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;     
于 2017-03-02T17:39:15.707 回答