IteratorAggregate en SeekableIterator tegelijk implementeren

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Senior DevOps-ontwikkelaar eIDAS

Functie­omschrijving Burgers en bedrijven veilig en betrouwbaar digitaal toegang geven tot diensten en producten van het ministerie van Economische Zaken en Klimaat. Als senior DevOps-ontwikkelaar bouw je daar letterlijk aan mee. En dat doe je bij DICTU: een van de grootste en meest vooruitstrevende ICT-dienstverleners van de Rijksoverheid. Jij werkt mee aan de doorontwikkeling van eIDAS, dat staat voor Electronic IDentification Authentication and trust Services. Deze koppeling maakt de grensoverschrijdende authenticatie op overheidswebsites binnen de Europese Unie mogelijk. Het ministerie van Economische Zaken en Klimaat heeft één moderne toegangspoort voor zijn diensten en inspecties. Enkele daarvan zijn dankzij eIDAS inmiddels

Bekijk vacature »

Write Down

Write Down

03/08/2012 18:51:25
Quote Anchor link
Hi,

Ik probeer in een van classes zowel de SeekableIterator als de IteratorAggregate te implementeren. Alleen, dan krijg ik de volgende fout:


Fatal error: Class E\Core\Database\DataResult cannot implement both Iterator and IteratorAggregate at the same time in /home/user/public_html/lib/ECMS/Core/Database/DataResult.php on line 11

Ik zie wel in dat beide interfaces de Iterator class implementeren, maar dit kan toch de bedoeling niet zijn?

Weet iemand hier een oplossing voor?
Gewijzigd op 04/08/2012 15:58:05 door Write Down
 
PHP hulp

PHP hulp

29/09/2020 06:35:23
 
Write Down

Write Down

04/08/2012 20:32:51
Quote Anchor link
Bump :-)
 
Pim -

Pim -

08/08/2012 12:07:49
Quote Anchor link
Die foutmelding is heel logisch. Een klasse kan ofwel zelf een iterator zijn, ofwel een iterator aan kunnen bieden. Als je beide wil implementeren weet PHP niet welke iterator hij moet nemen.

Ik denk dat je wil dat de iterator die de getIterator() functie aanbiedt, SeekableIterator implementeert, dat kan toch prima?
 
Write Down

Write Down

08/08/2012 13:33:17
Quote Anchor link
Hoe zou ik dat dan moeten doen? Je kan toch interface implementeren bij een bepaalde functie?
 
Pim -

Pim -

08/08/2012 18:14:30
Quote Anchor link
Laat je code eens zien.
 
Pim -

Pim -

12/08/2012 13:05:28
Quote Anchor link
Zo kan je ze allebei gebruiken:
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
<?php
class EoAIterator implements SeekableIterator
{
    // bla bla bla

    function seek($i)
    {

        // ...
    }
}


class EoAClass implements IteratorAggregate
{
    function
getIterator()
    {

        return new EoAIterator($this->data);
    }
}

?>
 
Write Down

Write Down

14/08/2012 10:49:01
Quote Anchor link
Excuses voor de late reactie. Bedankt Pim, dat is inderdaad een mooie oplossing.
Gewijzigd op 14/08/2012 18:14:18 door Write Down
 
Write Down

Write Down

15/08/2012 12:31:12
Quote Anchor link
Misschien toch even jullie mening vragen over hoe ik alles heb geïmplementeerd. Ik wou dit dus doen om te kunnen werken met resultaten uit de database. Meer specifiek, als het gaat om queries waarvan ik bepaalde gegevens terug verwacht. Dus denk daarbij vooral aan select queries.

De volgende klasse wordt gebruikt vanuit de database klasse. Deze geeft altijd een Result (of een exception) terug.

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
<?php
namespace E\Core\Database;

class Result {
    private $result;
    
    public function __construct(\PDOStatement $result) {
        $this->setResult($result);
    }

    
    protected function setResult($result) {
        $this->result = $result;
    }

    
    protected function getResult() {
        return $this->result;
    }
}

?>


De eerste uitbreiding, bedoeld bijvoorbeeld een insert statement ziet er als volgt uit:
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
<?php
namespace E\Core\Database;
use E\Core\Database\Result;

class ManipulationResult extends Result implements \Countable {
    public function __construct(Result $result) {
        $this->setResult($result->getResult());
    }


    public function count() {
        return $this->getResult()->rowCount();
    }
}

?>


De klasse waarmee ik dan select statements e.t.c. wil verwerken ziet er als volgt uit:
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
<?php
namespace E\Core\Database;
use E\Core\Database\Result;
use E\Core\Database\SeekableResult;
use E\Core\Database\SeekableIteratorInterface;

class DataResult extends Result implements \IteratorAggregate, \Countable, SeekableIteratorInterface {
    
    private $seekableResult;

    public function __construct(Result $result) {
        $this->setResult($result->getResult()->fetchAll(\PDO::FETCH_ASSOC));
        $this->setSeekableResult($this->getResult());
    }

    
    private function setSeekableResult(array $result) {
        $this->seekableResult = new SeekableResult($result);
    }

    
    private function getSeekableResult() {
        return $this->seekableResult;
    }

    
    public function getIterator() {
        $result = new SeekableResult($this->getResult());
        return $result->getItterator();
    }


    public function count() {
        return count($this->getResult());
    }

////-->SeekableIteratorInterface
    public function current() {
        return $this->getSeekableResult()->current();
    }


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


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


    public function rewind() {
        $this->getSeekableResult()->rewind();
    }


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


    public function valid() {
        $this->getSeekableResult()->valid();
    }

    ////
}
?>


De interface die ik in de bovenstaande klasse implementeer, SeekableIteratorInterface, is eigenlijk dezelfde als de SeekableIterator van PHP. (Alleen, ik moest dit zo doen, net door het probleem dat ik mijn eerste bericht aankaartte.)

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
namespace E\Core\Database;

interface SeekableIteratorInterface {
    public function current();
    public function key();
    public function next();
    public function rewind();
    public function seek($position);
    public function valid();
}


?>


En dan uiteindelijk de klasse die het mogelijk maakt om 'Seekable' te gebruiken:
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
<?php
namespace E\Core\Database;

class SeekableResult implements \SeekableIterator{
  
    private $result;
    private $position;
    
    public function __construct(array $result) {
        $this->setResult($result);
        $this->setPosition(0);
    }

    
    private function setResult($result) {
        $this->result = $result;
    }

    
    public function getResult() {
        return $this->result;
    }

    
    private function setPosition($position) {
        $this->position = $position;
    }

    
    private function getPosition() {
        return $this->position;
    }


    public function current() {
        $result = $this->getResult();
        $current = $result[$this->getPosition()];
        if(is_array($current)) {
            $current = (object) $current;
        }

        return $current;
    }


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


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


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


    public function seek($position) {
        $this->setPosition($position);
        if(!is_int($this->getPosition())) {
            throw new \InvalidArgumentException('Seek position must be an integer.');
        }

        if (!$this->valid()) {
            throw new OutOfBoundsException('Invalid seek position.');
      }
    }


    public function valid() {
        $result = $this->getResult();
        return isset($result[$this->getPosition()]);
    }

    
    public function getItterator() {
        return new \ArrayIterator($this->result);
    }
}

?>


Graag jullie meningen!
 
Write Down

Write Down

16/08/2012 14:23:52
Quote Anchor link
*Slaat zichzelf*

Ik heb ontdekt dat ArrayIterator de SeekableInterface implementeert. M.a.w. ik kan die gewoon lekker gebruiken...
 
Pim -

Pim -

16/08/2012 18:21:42
Quote Anchor link
Ik snap niet helemaal wat het Decorator patroon hier voor nut heeft.
Reguliere extension werkt toch prima?
 
Write Down

Write Down

16/08/2012 19:50:37
Quote Anchor link
Dit heb ik toch ook niet Pim? Maar goed, ik denk dat jij eerder doelt waarom ik ManipulationResult niet extend naar DataResult?
 



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.