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

dzieki