【问题标题】:json_encode giving recursion errorjson_encode 给出递归错误
【发布时间】:2013-06-18 14:39:51
【问题描述】:
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 没问题吧?

【问题讨论】:

  • 你能把代码粘贴到simple_html_dom.php
  • 上传太大了,会在问题空间发垃圾。无论如何,它是 sourceforge 的简单 html 解析器的默认文件

标签: php ajax json


【解决方案1】:

问题显然在于您试图在不适合它的情况下调用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-&gt;self$foo 是同一个对象。事实上,你可以做$foo-&gt;self-&gt;self-&gt;self,它会工作得很好。这是一个非常简单的递归结构。你的可能有点复杂,但原则上没有什么不同。这不能用 JSON 表示。 json_encode遇到递归会报错。

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

return $title[0]->plaintext;

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

【讨论】:

  • 嗨,->plaintext 确实消除了错误,我想我知道你的意思。谢谢
  • 让我继续阅读它以尝试理解它:x 非常感谢 Lonesomeday。谢谢。
  • 非常高兴能提供帮助。
【解决方案2】:

重现问题的简单示例

<?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]; 会解决这个问题。

【讨论】:

    【解决方案3】:

    您想完成什么,使用 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"));
    

    【讨论】:

    • 嗨,是的,Ajax,是的,使用 POST。 lonesomeday 上面有一个很好的解释。使固定。感谢您的帮助。尽管如此,欢迎使用 StackOVERFLOW!
    【解决方案4】:

    有时 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;     
    

    【讨论】:

      猜你喜欢
      • 2015-02-13
      • 2021-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多