Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP5]Funkcja zwrotna
Forum PHP.pl > Forum > PHP > Object-oriented programming
lDoran
  1. <?php
  2. class Student
  3. {
  4. private $_id;
  5. private $_name;
  6.  
  7. public $_courses;
  8.  
  9. public function __construct($id, $name)
  10. {
  11. $this -> _id = $id;
  12. $this -> _name = $name;
  13.  
  14. $this -> courses = new CourseCollection();
  15. $this -> courses -> setLoadCallBack('_loadCourses', $this);
  16. }
  17.  
  18. public function getName()
  19. {
  20. return $this -> _name;
  21. }
  22.  
  23. public function getID()
  24. {
  25. return $this -> _name;
  26. }
  27.  
  28. private function _loadCourses(Collection $col)
  29. {
  30. $arCourses = StudentFactory::getCoursesForStudent($this -> _id, $col);
  31. }
  32.  
  33. public function __toString()
  34. {
  35. return $this -> _name;
  36. }
  37. }
  38. ?>
  1. <?php
  2. require_once('class.KeyInvalidException.php');
  3. require_once('class.KeyInUseException.php');
  4.  
  5. class Collection
  6. {
  7. private $_members = array();
  8. private $_onLoad; //funkcja zwrotna
  9. private $_isLoaded = false; //flaga określająca, czy funkcja zwrota została już wysłana
  10.  
  11. public function addItem($obj, $key = null)
  12. {
  13. $this -> _checkCallBack();
  14.  
  15. if($key)
  16. {
  17. if(isset($this->_members[$key]))
  18. throw new KeyInUseException("Klucz \"$key\" jest już zajęty!");
  19. else
  20. $this->_members[$key] = $obj;
  21. }
  22. else
  23. $this->_members[] = $obj;
  24. }
  25.  
  26. public function removeItem($key)
  27. {
  28. $this -> _checkCallBack();
  29.  
  30. if(isset($this->_members[$key]))
  31. unset($this->_members[$key]);
  32. else
  33. throw new KeyInvalidException("Błędny klucz \"$key\"!");
  34. }
  35.  
  36. public function getItem($key)
  37. {
  38. $this -> _checkCallBack();
  39.  
  40. if(isset($this->_members[$key]))
  41. return $this->_members[$key];
  42. else
  43. throw new KeyInvalidException("Błędny klucz \"$key\"!");
  44. }
  45.  
  46. public function keys()
  47. {
  48. $this -> _checkCallBack();
  49.  
  50. return array_keys($this->_members);
  51. }
  52.  
  53. public function length()
  54. {
  55. $this -> _checkCallBack();
  56.  
  57. return sizeof($this->_members);
  58. }
  59.  
  60. public function exists($key)
  61. {
  62. $this -> _checkCallBack();
  63.  
  64. return (isset($this->_members[$key]));
  65. }
  66.  
  67. /*
  68. Ta metoda pozwala na zdefiniowanie funkcji, którą
  69. należy wywołać, aby wypełnić kolekcję.
  70. Jedynym parametrem tej funkcji powinna być
  71. kolekcja do wypełnienia.
  72. */
  73. public function setLoadCallBack($functionName, $objOrClass = null)
  74. {
  75. if($objOrClass)
  76. $callback = array($objOrClass, $functionName);
  77. else
  78. $callback = $functionName;
  79.  
  80. //sprawdzanie czy funkcja zwrotna da się wywołać
  81. if(!is_callable($callback, false, $callableName))
  82. {
  83. throw new Exception("Funkcja zwrotna $callableName nieprawidlowa!");
  84. return false;
  85. }
  86. $this -> _onLoad = $callback;
  87. }
  88.  
  89. private function _checkCallBack()
  90. {
  91. if(isset($this -> _onLoad) && !$this -> _isLoad)
  92. {
  93. $this -> _isLoaded = true;
  94. call_user_func($this -> _onLoad, $this);
  95. }
  96. }
  97. }
  98. ?>


Błąd zwracany przez przeglądarkę
Cytat
Funkcja zwrotna Student::_loadCourses nieprawidlowa!
Student #1 nie istnieje w bazie danych!


Nie rozumiem dlaczego Collection::setCallBack() nie może wywołać Student::_loadCourses worriedsmiley.gif
Zyx
Słowo private przy deklaracji Student::_loadCourses() coś Ci mówi? Jeśli nie, to poczytaj sobie, co ono znaczy, ponieważ to jest klucz do rozwiązania Twojego problemu.

Tak na marginesie:

  1. if($objOrClass)
  2. $callback = array($objOrClass, $functionName);
  3. else
  4. $callback = $functionName;


Usuń ten kod z cyklu "Masło maślane" - przecież to jest kombinowanie pod górę. Jak komuś będzie zależało, by wywołać metodę obiektu, to niech poda od razu prawidłową tablicę.
lDoran
Dzięki za pomoc, banalny błąd nie zwróciłem na to nawet uwagi, ale co by nie było wszystko toczka w toczkę jest w książce('PHP5 Zaawansowane programowanie').
Crozin
1) public $_courses; ten znak podkreślenia chyba Ci się przypadkiem wkradł - zważywszy na to, że później odwołujesz się do courses
2) Co do private - chyba każde jego użycie w Twoim-nie-Twoim kodzie jest błędne. Tego wyjątkowo restrykcyjnego modyfikatora powinno używać się tylko wtedy, gdy dana składowa/metoda obiektu jest częścią jakiegoś "pobocznego mechanizmu" używanego wewnątrz obiektu. Normalnie podstawowym modyfikatorem powinien być protected - nie ma potrzeby zamykania sobie możliwości wykorzystania danej klasy jako nadrzędnej (chodzi o dziedziczenie).
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.