Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Implementacja interfejsu IteratorAggregate
Forum PHP.pl > Forum > PHP > Object-oriented programming
lukasz_jaw
Witam
Chce zastosowac konstrukcje foreach dla obiektu implementujacego nazwany IteratorAggregate. Mam klase Collection w plku class.Collection.php ktora zawiera elementy:
Kod
<?php

    class Collection implements IteratorAggregate {
        private $_members = array();
        private $_onload; //funkcja zwrotna
        private $_isLoaded = false;  //flaga okreslajaca czy funkcja zwrotna zostala juz wywolana
        
        public function addItem($obj, $key = null) {
            $this->_checkCallback();
        
            if($key) {
                if(isset($this->_members[$key])) {
                    throw new KeyInUseException("Klucz \"key\" jest juz zajety");
                } else {
                    $this->_members[$key] = $obj;
                }
            } else {
                    $this->_members[] = $obj;
            }
        }
        
        public function removeItem($key) {
        $this->_checkCallback();
            if(isset($this->_members[$key])) {
                unset($this->_members[$key]);
            } else {
                    throw new KeyInvalidException("Bledny klucz \"$key\" !");
            }
        }
        
        public function getItem($key) {
        $this->_checkCallback();
            if(isset($this->_members[$key])) {
                return $this->_members[$key];
            } else {
                throw new KeyInvalidException("Bledny klucz \"$key\" !");
            }
        }
        
        public function keys() {
        $this->_checkCallback();
            return array_keys($this->_members);
        }
        
        public function length() {
        $this->_checkCallback();
            return sizeof($this->_members);
        }
        
        public function exists($key) {
        $this->_checkCallback();
            return (isset($this->_members[$key]));
        }
        
        public function setLoadCallback($functionName, $objOrClass = null) {
            if($objOrClass) {
                $callback = array($objOrClass, $functionName);
            } else {
                $callback = $functionName;
            }
        
        
        //spr czy funkcje zwrotna da sie wykonac
        if(!is_callable($callback, false, $callableName)) {
            throw new Exception("Funkcja zwrotna $callableName nieprawidlowa ");
            return false;
        }
            $this->_onload = $callback;
    }
        // spr czy funkcja zwrotna zostala zdefiniowana a jesli tak, czy zostala juz wywolana. Jesli nie zostaje ona wywolana
        private function _checkCallback() {
            if(isset($this->_onload) && !$this->_isLoaded) {
                $this->_isLoaded = true;
                call_user_func($this->_onload, $this);
            }
        }
        
        public function getIterator() {
            $this->_checkCallback();
            return new CollectionIterator($this);
        }
}


?>


ktore maja byc iterowane przez klase class.CollectionIterator.php

Kod
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++;
        }        
    }
?>


Pliki klasy Student :

Kod
<?php
    require_once("class.Course.php");
    
    class Student {
        private $_id;
        private $_name;
        
        public $courses;
        
        public function __construct($id, $name) {
            $this->_id = $id;
            $this->_name = $name;
            
            $this->courses = new CourseCollection();
            $this->courses->setLoadCallback('_loadCourses', $this);
        }
        
        public function getName() {
            return $this->_name;
        }
        
        public function getID() {
            return $this->_id;
        }
        
        public function _loadCourses(Collection $col) {
            $arCourses = StudentFactory::getCoursesForStudent($this->_id, $col);
        }
        
        public function __toString() {
            return $this->_name;
        }
    }
?>


Plik class.Course.php

Kod
<?php

    require_once("class.Student.php");
    require_once("class.Collection.php");

    class Course {
        private $_id;
        private $_name;
        private $_courseCode;
        
        function __construct($id, $courseCode, $name) {
            $this->_id = $id;
            $this->_name = $name;
            $this->_courseCode = $courseCode;
        }
        
        public function getName() {
            return $this->_name;
        }
        
        public function getID() {
            return $this->_id;
        }
        
        public function getCourseCode() {
            return $this->_courseCode;
        }
        
        public function __toString() {
            return $this->_name;
        }
    }
    
    class CourseCollection extends Collection {
        public function addItem(Course $obj, $key = null) {
            parent::addItem($obj, $key);
        }
    }
?>


klasa class.StudentFactory.php zawiera 2 metody statyczne odpowiedzialna za odczyt z bazy danych informacji o kursach i studentach:

Kod
<?php
    
    require_once("class.Student.php");
    require_once("class.Course.php");
    
    class StudentFactory {
    
        private static function _getConnection() {
            static $hDB;
            
            if(isset($hDB)) {
                return $hDB;
            }
            
            $hDB = pg_connect("host=.....pl dbname=..... user=..... password=.....")
                or die("Blad polaczenia z baza danych");
                return $hDB;
        }
    
        public static function getStudent($id) {
            $sql = "Select * FROM \"student\" WHERE \"student_id\" = $id";
            $res = pg_query(StudentFactory::_getConnection(), $sql);
            
            if(pg_num_rows($res)) {
                $objs = array();
                while($row = pg_fetch_assoc($res)) {
                $objs[] = new Student($row['student_id'],$row['nazwa']);
                }
            return $objs;
            }
            else {
                throw new Exception("Student $id nie istniejeee");
            }
        }
        
        public static function getCoursesForStudent($id, $col) {
            
            $sql = "Select \"kurs\".\"kurs_id\", \"kurs\".\"kurs_kod\", \"kurs\".\"nazwa\"
                    FROM \"kurs\",\"student_kurs\" WHERE \"kurs\".\"kurs_id\" = \"student_kurs\".\"kurs_id\"
                    AND \"student_kurs\".\"student_id\" = $id ";
            
            $res = pg_query(StudentFactory::_getConnection(), $sql);
            $data = pg_fetch_assoc($res);
            $num = pg_num_rows($res);

                if(isset($data)) {
                    $objCourse=array();
                    foreach($data as $datum) {
                        $objCourse = new Course($datum['kurs_id'], $datum['kurs_kod'], $datum['nazwa']);
                        $col->addItem($objCourse, $objCourse->getCourseCode());
                    }
                }
        }
    }
?>


Ostatnia rzecz plik testowy :

Kod
<?php
    
        ini_set( 'display_errors', 'On' );
        error_reporting( E_ALL );

    require_once ("class.StudentFactory.php");
    
    $objStudent = StudentFactory::getStudent(1);
    foreach ($objStudent->courses as $key=>$objCourse) {
        print $objStudent .'jest zapisany na kurs'. $objCourse . "<br> \n";
    }
    echo "<pre>";
    print_r($objStudent);
    echo "</pre>";
    
    //print_r($obj);
    
?>


I zamiast klasa CollectionIterator.php implentowala intefejs IteratorAggregate i wyswietlala dane o kursie wyswietla blad:

Kod
Notice: Trying to get property of non-object in /home/ltomczyk/domains/ltomczyk.pl/public_html/klasy/klasaCollectionIterator/testCollection.php on line 31

Warning: Invalid argument supplied for foreach() in /home/ltomczyk/domains/ltomczyk.pl/public_html/klasy/klasaCollectionIterator/testCollection.php on line 31


Prosze o wskazowki co jest nie tak smile.gif . Po zastosowaniu print_r($obj) dostaje informacje ze to jest Object - nie tablica wiec nie wiem czemu nie dziala. Posiadam wesje php 5.2
dzieki
aniolekx
StudentFactory::getStudent(1) tutaj zwracasz tablice, widać to w kodzie.

zamiast print_r użyj var_dump, zobaczysz ze to tablica.

prawdopodobnie zamiast $objs = array(); powinno byc $objs = new Collection;
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.