Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[PHP] chaining methodes

Pagina: 1
Acties:

Onderwerpen


  • ZeroXT
  • Registratie: December 2007
  • Laatst online: 24-11 10:41
Beste mensen,

Ik probeer een dom inspector te maken die de gebruiker instaat stelt om een url op te geven en met bepaalde selectors de document object model kan benaderen van de broncode van de desbetreffende url.

Nu wil ik gebruik maken van methode chaining zoals dit:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Dom
{
    private $huidig;

    public function getTag($tag)
    {
        $this -> $huidig = $tag;
        //Code die op zoek gaat naar de tag 
        return $this;
    }
}

$dom= new Dom();
$dom-> getTag('div') -> getTag('ul');


Nu wil ik graag alle image-tags filteren uit alle divs (als voorbeeld) door de onderstaande code:

PHP:
1
2
3
4
5
6
$images = $dom-> getTag('div') -> getTag('img');
foreach($images as $image)
{
    echo $image;
}
}


Kan iemand mij een duwtje in de rug geven hoe ik deze constructie het beste kan opzetten? Ik weet dat je met $this de methodes kan chainen alleen lukt het me niet om dan de tags terug te krijgen want hij returned namelijk het gehele object zelf.

  • ZpAz
  • Registratie: September 2005
  • Laatst online: 24-11 22:29
In je object zowel de magic method toArray* en toString implementeren.

*Zie hieronder, die is correct.

[ Voor 30% gewijzigd door ZpAz op 01-03-2012 17:08 ]

Claude: "Domain patterns emerge from iteration, not generation." - Tweakers Time Machine Extension | Chrome : FF


  • mithras
  • Registratie: Maart 2003
  • Niet online
Als je $images in een foreach wilt stoppen, dan moet je de interface iterator implementeren. Oftwel: na elke Dom::getTag() sla je het resultaat op (wat jij doet moet Dom::huidig) om er daarna doorheen te itereren.

Voorbeeldje:
PHP:
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
class Dom implements Iterator {
    private $position = 0;
    private $tag;

    public function getTag ($selector)
    {
        // Haal $tag op met $selector;
        $this->tag = $tag;
        
        return $this;
    }

    public function rewind() {
        $this->position = 0;
    }

    public function current() {
        return $this->tag[$this->position];
    }

    public function key() {
        return $this->position;
    }

    public function next() {
        ++$this->position;
    }

    public function valid() {
        return isset($this->tag[$this->position]);
    }
}


Je moet hier wel mee uitkijken: als je itereert in bovenstaand geval, dan moet Dom::tag wel een array zijn of ArrayAccess implementeren. Je zoektocht naar een tag moet dus altijd een itereerbaar resultaat opleveren, of je gaat vreemde resultaten krijgen.

Ook zou ik je adviseren om dan wat meer abstractie te implemteren. Je hebt een Dom document waarin je verschillende DomNodes hebt. Als je zoekt naar een tag krijg je een of meerdere nodes terug die zich in een DomList verpakken. Mocht je hier niet zo 1-2-3 uitkomen, dan moet je eens naar de DOM extensie van php kijken ;)

  • TheNephilim
  • Registratie: September 2005
  • Laatst online: 11:39

TheNephilim

Wtfuzzle

Is het probleem nou het chainen of de dom-inspector?

  • armageddon_2k1
  • Registratie: September 2001
  • Laatst online: 27-07 10:18
Toevallig heeft SensioLabs componenten gemaakt die dat scrapen van content precies kunnen. De 'baas' van Symfony2 heeft hier een web scraper van gemaakt:

https://github.com/fabpot/Goutte

Ik zou hier zeker eens naar kijken!

[ Voor 4% gewijzigd door armageddon_2k1 op 01-03-2012 16:48 ]

Engineering is like Tetris. Succes disappears and errors accumulate.