call to a member function children() on a non-object

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Daniel van Seggelen

Daniel van Seggelen

22/08/2018 15:07:19
Quote Anchor link
Als ik onderstaande code run, dan krijg ik de foutmelding in de titel.
Ik probeer dat te omzeilen, maar dat gaat niet. Weet iemand wat ik verkeerd doe?


Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
foreach($detail_html->find('div[class=row grid]') as $gg)
                            {                            
                        
                                $oppervlakte =  $gg->children(0)->next_sibling()->next_sibling()->children(0)->next_sibling()->children(0)->children(0)->children(0)->next_sibling();
                                $house_type = $gg->children(0)->next_sibling()->children(0)->next_sibling()->children(0)->children(0)->children(0)->next_sibling();



    $isObject = false;
    if ( false !== $gg->children(0)->next_sibling()->next_sibling()->next_sibling()->children(0)->next_sibling()->children(0)->children(0)->children(0)->next_sibling()  ) {
        $isObject = true;
        $aantal = $gg->children(0)->next_sibling()->next_sibling()->next_sibling()->children(0)->next_sibling()->children(0)->children(0)->children(0)->next_sibling();
    }
    if($isObject){
    $arr_test[] = array('rooms',trim(strip_tags( $aantal)));    
    }
 
PHP hulp

PHP hulp

18/04/2024 10:59:11
 
Thomas van den Heuvel

Thomas van den Heuvel

22/08/2018 15:39:09
Quote Anchor link
Allereerst, fix je inspring eens. Een treinongeluk zit er nog overzichtelijker uit.

Vervolgens, voorzie je code eens van commentaar, zodat i.i.g. voor een ongeïnitieerd persoon duidelijk is wat je probeert te doen.

Dan over het topic zelf: is dit een soort van webscraper ofzo? Uitgaan van een specifieke positie van een bepaald element is nogal foutgevoelig lijkt mij. Op het moment dat de layout verandert of varieert gaat dit al snel stuk. Ik zou je dan ook aanraden om deze informatie gestructureerd uit te lezen via een feed of API.

We hebben ook niet zoveel aan de foutmelding omdat:
- er ik weet niet hoeveel keer er in het bovenstaande fragment "children" staat, bij welke children loopt deze vast?
- we niet weten hoe "$gg" er uitziet

Dus, eh. Gg.
 
Daniel van Seggelen

Daniel van Seggelen

22/08/2018 16:57:42
Quote Anchor link
Quote:
Allereerst, fix je inspring eens. Een treinongeluk zit er nog overzichtelijker uit.


Voor jou wellicht, maar het is nogal duidelijk wat zich hier afspeelt.

1) Het is duidelijk dat het in en loop werkt.Het is ook duidelijk dat de childrens en nextsibblings staan. Even tellen dat weet je hoeveel. Daar gaat het niet om. Het komt erop neer dat in sommige lussen deze informatie wel bestaat en bij andere niet.

2) Het enige wat ik dus wil is wanneer deze " $aantal" dus niet bestaat dat hij niet vastloopt op een FATAL error, maar dat hij de lus gewoon door blijft lopen.

Daniel
 
Rob Doemaarwat

Rob Doemaarwat

22/08/2018 17:14:34
Quote Anchor link
Daniel van Seggelen op 22/08/2018 16:57:42:
Voor jou wellicht, maar het is nogal duidelijk wat zich hier afspeelt.

Voor jou wellicht. Maar je vraagt ons hier om even voor nop jouw probleem op te lossen. Dan is misschien niet al teveel moeite om het een beetje netjes te presenteren?

Als ik snel kan zien wat er precies gebeurt, dan wil ik er best even naar kijken. Maar als ik eerst uit moet zoeken wat bij wat hoort, en daarvoor ook nog steeds van links naar rechts moet scrollen dan klik ik gewoon verder.
 
Daniel van Seggelen

Daniel van Seggelen

22/08/2018 17:30:12
Quote Anchor link
Quote:
Als ik snel kan zien wat er precies gebeurt, dan wil ik er best even naar kijken. Maar als ik eerst uit moet zoeken wat bij wat hoort, en daarvoor ook nog steeds van links naar rechts moet scrollen dan klik ik gewoon verder.


Dat hoeft helemaal niet. Ik zeg dus ook dat deze children , nextsiblings part soms wel bestaat en soms niet. Ik wil gewoon dat hij de fatal error skipt als hij niet bestaat en dat schijnt me niet te lukken
 
Ward van der Put
Moderator

Ward van der Put

22/08/2018 18:14:38
Quote Anchor link
Je zou met method_exists() of ReflectionClass::hasMethod() kunnen controleren of children() bestaat.
 
Thomas van den Heuvel

Thomas van den Heuvel

22/08/2018 19:40:39
Quote Anchor link
Van wat voor klasse is $detail_html uberhaupt?
 
Daniel van Seggelen

Daniel van Seggelen

23/08/2018 01:06:36
Quote Anchor link
$detail_html is een html string, wat via str_get_html SImple DOm word binnen gehaald:

http://simplehtmldom.sourceforge.net/

method exist en reflectionclass.hasmethod krijg ik niet werkend.
 
Ward van der Put
Moderator

Ward van der Put

23/08/2018 09:14:56
Quote Anchor link
Splits de method chain ...->...->...->... op in losse stappen en voeg daaraan een if toe die hetzij controleert of een methode bestaat, hetzij of er überhaupt een object van het juiste type ergens uit komt.
 
Ivo P

Ivo P

23/08/2018 12:46:10
Quote Anchor link
method_exit() hoef je mi. niet te gebruiken: de foutmelding zegt "on a non-object".

$gg is dus geen object. (zal wel FALSE of NULL zijn). Maar de controle of $gg een object is (en eventueel ook nog van de class X) zou voldoende moeten zijn.

Dwz: dat lost het eerste deel op, maar ik schat in dat als $gg wel een object is, het ook wel een van het verwachte type zal zijn.
Gewijzigd op 23/08/2018 12:47:10 door Ivo P
 
Paul Ulje

Paul Ulje

23/08/2018 15:53:57
Quote Anchor link
"Voor jou wellicht, maar het is nogal duidelijk wat zich hier afspeelt."

Ja, dat denk ik ook.
Hier wordt gepoogd van een webpagina een veldje uit te lezen.
Ik heb tevens de indruk dat er JS(on) wordt geplengd in een PHP syntax.

Maar gelukkig heb ik meer verstand van verzekeren. :-)
Gewijzigd op 23/08/2018 16:00:15 door Paul Ulje
 
Thomas van den Heuvel

Thomas van den Heuvel

23/08/2018 16:53:00
Quote Anchor link
Wat @Ward zei, schrijf een soort van trace functie die je ook informatie teruggeeft over waar het misgaat, zoiets dus:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<?php
// include simple_html_dom hier ergens
// ...


ob_start();
?>
<h2>random header</h2>
<p>introducution</p>
<div id="tree">
    <ul>
        <li>1<ul>
            <li>1.1<ul>
                <li>1.1.1<ul>
                    <li>1.1.1.1</li>
                </ul></li>
                <li>1.1.2</li>
            </ul></li>
        </ul></li>
        <li>2</li>
        <li>3<ul>
            <li>3.1</li>
            <li>3.2<ul>
                <li>3.2.1</li>
                <li>3.2.2</li>
            </ul></li>
        </ul></li>
    </ul>
</div><?php
$input
= ob_get_clean();

$html = str_get_html($input);
$tree = $html->find('div[id=tree] ul', 0); // returns an array of simple_html_dom_node's

$test = $tree->children(0)->children(0)->children(0)->children(0)->children(0)->next_sibling();
echo $test->innertext().'<hr>'; // 1.1.2

$trace = array(
    array('c', 0),  // children, index 0
    array('c', 0),  // children, index 0
    array('c', 0),  // children, index 0
    array('c', 0),  // children, index 0
    array('c', 0),  // children, index 0
    array('n'),     // next sibling
);

function
domTrace($in, $trace) {
    $step = 0;
    foreach ($trace as $action) {
        switch ($action[0]) {
            case
'c': // children
                if (method_exists($in, 'children')) {
                    if (isset($action[1])) { // was an index provided?
                        $in = $in->children($action[1]);
                    }
else {
                        $in = $in->children();
                    }

                    if ($in === NULL) {
                        throw new Exception('children not found in step '.$step);
                    }
                }
else {
                    throw new Exception('method children does not exist in step'.$step);
                }

            break;
            case
'n': // next_sibling
                $in = $in->next_sibling();
                if ($in === NULL) {
                    throw new Exception('sibling not found in step '.$step);
                }

            break;
            default:
throw new Exception('unknown op in step '.$step);
        }

        $step++;
    }

    return $in;
}


try {
    $test = $tree;
    $test = domTrace($test, $trace);
    echo $test->innertext(); // 1.1.2
} catch (Exception $e) {
    echo $e->getMessage();
}

?>
[end]

En als je de foutmeldingen stilzwijgend wil afhandelen zou je false kunnen retourneren in plaats van het throwen van een Exception.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.