Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [OOP] Iterowanie / interface Traversable
Forum PHP.pl > Forum > PHP > Object-oriented programming
guci0
Witam serdecznie!

Panowie lub Panie,
mam ogromna prośbe - siędzie nad tym już kilka ładnych godzin i zaraz będe
zmuszony poszukać młotka i dać sobie w głowę ...

Mam takie KLASY i INTERFEJSY:

Kod
interface Traversable {}

interface Iterator implements Traversable {
 function current();
 function key();
 function next();
 function rewind();
 function valid();
}

interface IteratorAggregate implements Traversable {
 public function getIterator();
}


i ...

Kod
class Collection implements IteratorAggregate {
...
public function getIterator() {
       $this->_checkCallback();
     return new CollectionIterator(clone $this);
   }
...
}

class CollectionIterator implements Iterator {

   private $_collection;
   private $_currIndex = 0;
   private $_keys;

   function __construct(Collection $objCol) {
      $this->_collection = $objCol;
      $this->_keys = $this->_collection->keys();
   }

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

   function valid() {
      return $this->_currIndex < $this->_collection->length();
   }

   function key() {
      return $this->_keys[$this->_currIndex];
   }

   function current() {
      return $this->_collection->getItem($this->_keys[$this->_currIndex]);
   }

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


Oczywiście nie wkleiłem całego kodu klasy Collection, sądzę iż nie
ma teraz takiej potrzeby. Przykład i implementacja klas/interfejsów biorę z ksiązki PHP5. Zaawansowane programowanie. Wiem, książka
ma sporo błędów i głównie właśnie jakieś psikusy zrobione są z interfejsami, choć w tym przypadku mogę się mylić...

Potrzebuje pomocy, wywolując program
APACHE zwraca:

Parse error: syntax error, unexpected T_IMPLEMENTS, expecting '{' in /Applications/MAMP/htdocs/folder/test/folder_base/class/class.Collection.php on line 8

Już nie wiem jak mam sobie z tym poradzić, dlatego
jeszcze raz proszę o POMOC!

Z góry BARDZO dziękuje
wszystkim zaangażowanym w rozwiązaniu problemu

Pozdrawiam

Paweł - guci0

P.S. Tak na marginesie to, coś słabo działa
edytor na forum (BBCODE)
Morkai
http://php.net/interface#language.oop5.int...es.examples.ex2

Interfejsy rozszerza się stosując słowo kluczowe extends, a nie implements.

Dlaczego stworzyłeś własne interfejsy Traversable, Iterator oraz IteratorAggregate?
guci0
Cytat(Morkai @ 16.10.2008, 22:09:55 ) *
http://php.net/interface#language.oop5.int...es.examples.ex2
Interfejsy rozszerza się stosując słowo kluczowe extends, a nie implements.
Dzieki, cos poszło - jednak teraz
jest zwracany błąd: Fatal error: Cannot redeclare class Iterator
Cytat(Morkai @ 16.10.2008, 22:09:55 ) *
Dlaczego stworzyłeś własne interfejsy Traversable, Iterator oraz IteratorAggregate?
Wiesz, programowania obiektowego jeszcze się uczę, a
w książce, przynajmniej tak mi sie wydaje, że tak "każą" ...

Jak inaczej moge skorzystać z wbudowanych interfejsów albo
jak mogę uniknąć błędu?
mike
Cytat(guci0 @ 16.10.2008, 22:41:31 ) *
Jak inaczej moge skorzystać z wbudowanych interfejsów?
Po prostu skorzystać. One są wbudowane.
Zerknij na to co już masz: SPL - Standard PHP Library
guci0
Cytat(mike @ 16.10.2008, 22:44:43 ) *
Zerknij na to co już masz: SPL - Standard PHP Library
Kurde, hmmm...
Nie wiem jak tego użyć.

Próbuje i próbuje, ale
cały czas nie ide do przodu tylko same nie wiadome...

Pomyśle jeszcze rano,
świeże siły - być może to coś da smile.gif
Crozin
Przeczytałeś treść błędu? smile.gif
Cytat
Fatal error: Cannot redeclare class Iterator
Co można przetłumaczyć jako:
Cytat
Błąd krytyczny: Nie można ponownie zadeklarować klasy Interator
Czyli taka klasa/interfejs już istnieje.

W książce zapewne podali kod tych klas/interfejsów, abyś wiedział jak one wyglądają.
guci0
Cytat(Crozin @ 17.10.2008, 08:09:55 ) *
W książce zapewne podali kod tych klas/interfejsów, abyś wiedział jak one wyglądają.
Już rozumiem, teraz zakomentowałem interfejsy w klasie Collection, następnie
zaimplementowałem interfejs IteratorAggegate (wbudowany).

Klasa Collection posiada metode publiczną getIterator(), która
to zwraca obiekt CollectionIterator, ten swoją drogą implementuje interfejs Iterator (wbudowany).

Output ProductCOLLECTION wygląda tak:
Kod
ProductCollection Object
(
    [_members:private] => Array
        (
            [1] => Product Object
                (
                    [id:private] => 1
                    [name:private] => name1
                    [promotion:private] => false
                    [new:private] => true
                )

            [4] => Product Object
                (
                    [id:private] => 2
                    [name:private] => name3
                    [promotion:private] => true
                    [new:private] => true
                )

        )

    [_onload:private] => 
    [_isLoaded:private] => 
)


Następnie chcąc przeIterować obiekt ProductCollection (dziedziczy po Collection, a wiec z interfejsami
też powinno być wszystko OK! [chyba?]),

Kod
 foreach ($objProductCollection as $key => $val) {
     echo "key/value: [$key -> $val]\n\n";
 }


i zwraca błąd: Catchable fatal error: Object of class Product could not be converted to string

Czy ja w ogóle ide w dobrą stronę?

EDIT: Idąc przykładem z http://pl2.php.net/manual/pl/language.oop5.iterations.php (trochę go zmieniłem, przede wszystkim zamiast wartości dodałem obiekty do klasy MyCollection, poprzez metode add(new Product("name"))

i wiem, że tu chodzi właśnie o OBIEKTY w Collection.

Mam, teraz cos takiego
Kod
MyCollection Object
(
    [items:private] => Array
        (
            [0] => Product Object
                (
                    [name:private] => nazwa 1
                )
            [1] => Product Object
                (
                    [name:private] => nazwa 2
                )
            [2] => Product Object
                (
                    [name:private] => nazwa 3
                )
        )
    [count:private] => 3
)


Jak mogę to przeITEROWAĆ? Miałobyć łatwo, a
nie jest - ah...

EDIT: A czy w ogóle jest sens tak to robić? Czy może
powinienem użyc GenericObjectCollection ? WALCZE dalej...
Morkai
Cytat(guci0 @ 17.10.2008, 08:26:26 ) *
Kod
 foreach ($objProductCollection as $key => $val) {
     echo "key/value: [$key -> $val]\n\n";
 }


i zwraca błąd: Catchable fatal error: Object of class Product could not be converted to string

Dodaj do klasy Product metodę __toString().
guci0
Cytat(Morkai @ 18.10.2008, 00:23:19 ) *
Dodaj do klasy Product metodę __toString().

Czy to jedyne wyjście?, na to zresztą
sam wpadłem - choć niedokońca właśnie o to mi chodziło, ale
wielkie dzieki za zainteresowanie

Pozrawiam

guci0
athabus
Jeśli chcesz użyć metody echo dla obiektu to koniecznie musi mieć on metode __toString(). Jeśli chcesz wyświetlić zawartość obiektu to możesz np. zrobić var_dump($value)
guci0
Cytat(athabus @ 18.10.2008, 10:51:10 ) *
Jeśli chcesz użyć metody echo dla obiektu to koniecznie musi mieć on metode __toString(). Jeśli chcesz wyświetlić zawartość obiektu to możesz np. zrobić var_dump($value)

Rozumiem i dzięki

guci0
starach
Pozwólcie że ze swoim pytaniem dokleję się tutaj.

Po jakiego diabła ten interfejs, do czego on służy, po co on jest?

Cytat
Interface to detect a class is traversable using foreach.
Wszyyyyystkoooo jaaasneee...

I nadal nie rozumiem po co on jest. Wszystkie kolekcje działają mi z zaimplementowanym tylko interfejsem Iterator.
batman
Intercafe Traversable jest po to stworzony, by interpreter języka wiedział, że dany obiekt może być interowany za pomocą pętli foreach. Implementacja tego interface-u nic nie da, ponieważ jest on pusty. Zamiast tego należy implementować interface Iterator.
mike
~orglee to masz za jakiś tandetny słownik.
Zerknij tu: Traversable
Zresztą wywaliłem z Twojego posta fragmety słownika. Nie wiem po kiego wała je wkleiłeś. Zajmowały sporo miejsca, robiły śmietnik a jak sam zauważyłeś nic nie wnoszą i nie tłumaczą.

Cytat(orglee @ 18.10.2008, 16:29:25 ) *
Po jakiego diabła ten interfejs, do czego on służy, po co on jest?
Czasami stosuje się puste interfejsy. W Javie mówi się na nie Marker Interface. Interfejsy takie nie nakazują implementacji czegokolwiek (bo niby co miałyby nakazywać skoro są puste) tylko oznaczają coś. Dobrym przykładem jest Clonable, interfejs nie wprowadza konieczności implementowania czegokolwiek tylko wskazuje na klasy, których obiekty mogą być klonowane.
Takim właśnie interfejsem jest Traversable. Oznacza on obiekty klas, które pozwalają na przechodzenie po sobie za pomocą pętli.
Cytat(orglee @ 18.10.2008, 16:29:25 ) *
Wszystkie kolekcje działają mi z zaimplementowanym tylko interfejsem Iterator.
Działa Ci bo Iterator dziedziczy po Traversable.
starach
Hmm zaraz zaraz. Interfejsy nie mogą implementować innych interfejsów. Aha dziedziczy! Ok teraz już rozumiem. Tak mi się wydawało, że do tego służy. Jednak przez wzgląd na brak możliwości implementowania interfejsów przez inne interfejsy jakoś mi się to nie kleiło. Dzięki.

mike: Dodatkowo dzięki za słownik. Już go sobie do zakładek dodałem. smile.gif

Swoją drogą na http://www.php.net/~helly/php/ext/spl/interfaceIterator.html, mogliby dodać notatkę, że Iterator rozszerza Traversable, bo tych diagramów to nigdy czytać mi się nie chce :F
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.