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

Co to za błąd, nie mogę rozwiązać problemu. Generuje on BIG BIG log na błąd 500 w obliczu. 133 000 000 bajtów. To spamowanie dziennika, aż do wyczerpania pamięci.json_encode podając błąd rekursji

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

?> 

Próbuję wyodrębnić dane z pliku HTML, inne ekstrakcji działa dobrze, z wyjątkiem powyższego, dając wiele problemów. Oddzieliłem ten zestaw kodu od jednego pliku PHP do przetworzenia i tego samego problemu.

Każdy pomysł? Używam jQuery Ajax z wieloma funkcjami na stronie głównej z $.ajax({
Jestem nowy w Ajax, dobrze jest mieć wiele Ajax na jednej stronie, prawda?

+0

można wkleić kod w 'simple_html_dom.php' – user20232359723568423357842364

+0

To jest zbyt duży, aby załadować, to spam przestrzeń pytanie. W każdym razie jest to domyślny plik prostego analizatora html na sourceforge – CodeGuru

Odpowiedz

9

Problem wyraźnie leży w Twoich próbując wywołać json_encode na coś nie nadaje się do niej:

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

Co możemy zapytać, czy $retrievetitle? Jaką to wartość? Cóż, znajdujemy go w definicji funkcji:

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

Tak wyraźnie jest to jakiś przedmiot. Nie jestem zaznajomiony z biblioteką simple_html_dom, ale prawdopodobnie jest to obiekt, który należy do tej biblioteki i reprezentuje element HTML. Być może jest to rodzimy obiekt DOMElement; Nie wiem

Jest jednak oczywiste, że jest to rodzaj struktury rekursywnej. To znaczy, w pewnym sensie zawiera się samo. Jest to całkowicie możliwe w PHP, ale nie można go reprezentować w łańcuchu JSON. Na przykład, w PHP

class Foo { 
    public $self; 

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

$foo->self jest tego samego obiektu jako $foo. Rzeczywiście, mógłbyś zrobić $foo->self->self->self i wszystko działałoby dobrze. Jest to bardzo prosta struktura rekurencyjna. Twój jest prawdopodobnie nieco bardziej złożony, ale nie różni się zasadniczo. To nie może być reprezentowane w JSON. json_encode spowoduje błąd podczas napotkania rekursji.

Wyobrażam sobie, że prawdopodobnie chciałeś zapisać treść tytułu, a nie sam tytuł. Krótko czytając API documentation for the library, wydaje się, że chcesz mieć właściwość plaintext. Nie jestem pewien, jak to działa (API jest, powiedzmy, rzadki), ale moje przypuszczenie byłoby następujące:

return $title[0]->plaintext; 

Ale to tylko wykształconych odgadnięcia.

+0

Cześć, -> tekst jawny usuwa błąd, myślę, że wiem co masz na myśli. Dzięki – CodeGuru

+0

Pozwól mi kontynuować czytanie, aby spróbować zrozumieć: x Dziękuję bardzo lonesomeday. Dziękuję Ci. – CodeGuru

+0

Bardzo się cieszę, że pomogłem. – lonesomeday

1

prosty przykład odtworzenie problemu

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

json_encode($o); 

Po json_encode() napotyka $ o-> ARR [0] == $ o to by zacząć ponownie $ O $ O-osiągnąć > arr [0], zacznij ponownie od $ o itd. w nieskończoność ad infinitum. Aby temu zapobiec, funkcja "zapamiętuje" każdy węzeł, który już przetworzył. Jeśli "zobaczy" ten sam węzeł ponownie, wyśle ​​ostrzeżenie o rekursji.
Obiekty simple_html_dom, które powróciły z twoich funkcji, prawdopodobnie mają odniesienie do ich obiektów macierzystych lub coś w tym stylu, powodując rekursję.
Tak, możereturn (string)$title[0]; i return (string)$rmb[0]; rozwiąże problem.

1

Co próbujesz osiągnąć, używając metody POST, aby wysłać źródło HTML. Następnie przeanalizowanie go po stronie serwera jest nieco nadmierne.

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

?> 

Jak wygląda Twoje połączenie AJAX? Czy ustawiłeś parametr typu na "POST"?

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

również powinieneś spróbować po prostu wywołać funkcję json_encode() samodzielnie. zobacz, czy dostałeś błąd.

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

Witaj, Tak, Ajax i Tak, używając POST. Lonesomeday miał świetne wyjaśnienie, jak wyżej. Naprawić. Dziękuję za pomoc. Niemniej jednak WITAMY W STACKOVERFLOW! – CodeGuru

1

Czasami metoda simple_html_dom.php nie będzie przesyłana do napisu zgodnie z oczekiwaniami. mam rozwiązany problem składni smyczkowy obsada:

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