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

Qual è l'errore, non riesco a risolvere il problema. Sta generando un GRANDE registro di GRANDE per errore 500 affrontato. 133.000.000 byte di dimensioni. Spamming il log fino alla memoria massima.json_encode con errore di ricorsione

<?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]; 
} 

?> 

Sto cercando di estrarre i dati da un file HTML, l'altro di estrazione funziona bene, tranne che per quanto sopra, dando un sacco di problema. Ho persino separato questo set di codice in modo specifico per un file PHP per l'elaborazione e lo stesso problema.

Qualche idea? Io uso jQuery Ajax con più funzioni nella home page con $.ajax({
Sono nuovo di Ajax, è giusto avere più Ajax in una sola pagina, giusto?

+0

Potete incollare il codice in 'simple_html_dom.php' – user20232359723568423357842364

+0

E 'troppo grande per caricare, sarà lo spam lo spazio domanda. Ad ogni modo è il file predefinito di semplice parser html su sourceforge – CodeGuru

risposta

9

Il problema è chiaramente nel vostro tentativo di chiamare json_encode su qualcosa non adatto per questo:

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

cosa, potremmo chiedere, è $retrievetitle? Che tipo di valore è? Bene, lo troviamo nella definizione della funzione:

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

Quindi chiaramente è una specie di oggetto. Non ho familiarità con la libreria simple_html_dom, ma presumibilmente si tratta di un oggetto che appartiene a quella libreria e rappresenta un elemento HTML. Forse è un oggetto nativo DOMElement; Non lo so.

Ciò che è chiaro, tuttavia, è che si tratta di una sorta di struttura ricorsiva. Vale a dire, in un certo senso contiene se stesso. Questo è perfettamente possibile in PHP, ma è impossibile rappresentare in una stringa JSON. Ad esempio, in PHP:

class Foo { 
    public $self; 

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

$foo->self è lo stesso oggetto $foo. In effetti, potresti fare $foo->self->self->self e funzionerebbe bene. Questa è una struttura ricorsiva molto semplice. Il tuo è probabilmente un po 'più complesso, ma non dissimile in linea di principio. Questo non può essere rappresentato in JSON. json_encode errore quando incontra la ricorsione.

Immagino che probabilmente si desidera memorizzare il contenuto del testo del titolo, piuttosto che l'elemento titolo stesso. Leggendo brevemente il API documentation for the library, sembra che tu voglia la proprietà plaintext. Io non sono molto sicuro di come questo funziona (l'API è, per così dire, scarsa) ma la mia ipotesi sarebbe il seguente:

return $title[0]->plaintext; 

Ma questa è solo un'ipotesi.

+0

Ciao, -> il testo in chiaro rimuove l'errore, penso di sapere cosa intendi. Grazie – CodeGuru

+0

Lasciami continuare a leggerlo per cercare di capirlo: x Grazie mille lonesomeday. Grazie. – CodeGuru

+0

Più che felice di aver aiutato. – lonesomeday

1

semplice esempio per ricreare il problema

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

json_encode($o); 

Una volta json_encode() incontra $ o-> arr [0] == $ o avrebbe dovuto ricominciare da capo con $ o, raggiungerà $ o- > arr [0], ricomincia da $ o e così via all'infinito. Per evitare ciò, la funzione "ricorda" ogni nodo già elaborato. Se "vede" nuovamente lo stesso nodo, lancia l'avviso di ricorsione.
Gli oggetti simple_html_dom restituiti dalle funzioni probabilmente hanno riferimento agli oggetti dei genitori o qualcosa del genere, causando la ricorsione.
Quindi, forsereturn (string)$title[0]; e return (string)$rmb[0]; risolverà il problema.

1

Cosa stai cercando di ottenere, utilizzando un metodo POST per inviare sorgenti HTML. Quindi analizzarlo sul lato server è un po 'eccessivo.

<?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]; 
} 

?> 

Che aspetto ha la chiamata AJAX? Hai impostato il parametro type su "POST"?

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

Inoltre, dovresti provare a chiamare la funzione json_encode() da sola. vedi se ricevi un errore

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

Ciao, Sì, Ajax e Sì utilizzando il POST. Lonesomeday ha avuto una grande spiegazione come sopra. Difficoltà. Grazie per l'aiuto. Tuttavia, BENVENUTO SU STACKOVERFLOW! – CodeGuru

1

A volte simple_html_dom.php non esegue il cast della stringa come previsto. Ho risolto problema sintassi della stringa di fusione:

$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;