Json_encode дает ошибку рекурсии

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

Что это за ошибка, я не могу решить эту проблему. Он генерирует BIG BIG log за ошибку 500. 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 на одной странице?

Ответ 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->self - это тот же объект, что и $foo. Действительно, вы могли бы сделать $foo->self->self->self, и все будет хорошо. Это очень простая рекурсивная структура. Возможно, вы немного сложнее, но не принципиально. Это невозможно представить в JSON. json_encode будет ошибочно, когда он встретит рекурсию.

Я предполагаю, что вы, вероятно, захотели сохранить текстовое содержимое заголовка, а не сам элемент заголовка. Коротко прочитав API-документацию для библиотеки, кажется, вам нужно свойство plaintext. Я не совсем уверен, как это работает (APi, скажем так, разрежен), но я предполагал следующее:

return $title[0]->plaintext;

Но это всего лишь образованная догадка.

Ответ 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 и т.д. ad infinitum, Чтобы предотвратить это, функция "запоминает" каждый node, который уже обработан. Если он "видит" тот же самый node снова, он выдает предупреждение о рекурсии.
Объекты 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"));

Ответ 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;