Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: wywołanie metody po uzupełnieniu wartości
Forum PHP.pl > Forum > PHP > Object-oriented programming
pag-r
Witam.
Może tytuł nie specjalnie opisuję to co chce uzyskać, ale głowie się nad pewnym problemem i niespecjalnie wiem nawet jak go prawidłowo nazwać. Mianowicie korzystając z chainingu chcę wykonać metodę po uzupełnieniu kilku innych wartości z klasy.
  1.  
  2. //kod zmodyfikowany
  3.  
  4. class DB {
  5.  
  6. private $table;
  7. private $select;
  8. private $where;
  9. private $prepareQuery;
  10.  
  11. protected function table($table) {
  12. $this->table = $table;
  13. return $this; //zapomniałem dodać wcześniej
  14. }
  15.  
  16. protected function select($args) {
  17. $this->select = "select explode(',' , $args) from ";
  18. return $this; //zapomniałem dodać wcześniej
  19. }
  20.  
  21. protected function where($clause) {
  22. $this->where = $clause;
  23. return $this; //zapomniałem dodać wcześniej
  24. }
  25.  
  26. private function prepareQuery() {
  27. $this->prepareQuery = $this->select . $this->table . ' ' . $this->where;
  28. }
  29.  
  30. private function executeQuery() {
  31. //zwracane pola z tabeli;
  32. }
  33.  
  34. }
  35.  
  36. class Cos extends DB {
  37.  
  38. public function __construc() {
  39. parent::_construct();
  40. }
  41.  
  42. public function cos() {
  43. $rows = $this->select('field')->from('tableName')->where('field = 1');
  44. var_dump($rows);
  45. }
  46.  
  47. }
  48.  

I chodzi mi o to, żeby taki zapis wykonywał funkcje executeQuery, ale dopiero po sprawdzeniu wszystkich argumentów czyli jeśli zrobiłbym tylko
  1. $rows = $db->select('field')->from('tableName');
to też miałoby zadziałać.
Crozin
Już pomijając fakt, że ten kod jedynie więcej szkody niż pożytku Nairobi:
1. Twoje metody są chronione, a powinny być publiczne.
2. Powinieneś w każdej z nich zwracać jakiś obiekt - tu konkretnie $this.
3. W żaden normalny sposób nie wywołasz automatycznie metody prepare() - dlaczego nie chcesz zrobić tego ręcznie?
pag-r
Pomijając to, że zapomniałem dodać faktycznie return $this wszędzie i to jest tylko przykładowy kod, który w rzeczywistości jest zabezpieczony escapestringami itd, pomijając fakt, że wcale nie muszą być public skoro będą używane w klasie potomnej przez extends to dlaczego w żaden sposób nie uda mi się tego zrobić? Nie chcę tego robić ręcznie bo chcę utrzymać porządek w kodzie a z ręcznym zapisem będzie to wyglądać dziwnie.
  1. $rows = $db->select('field')->table('tableName')->executeQuery(); // ?

Chce uniknąć właśnie tego executeQuery na końcu.
nospor
Pomijajac to, ze jest to bezsensu, to jest to bezsensu....

Skoro sie upierasz, to w wal te executeQuery na koncu funkcji table i juz. Masz automatycznie wywolane, ale patrz wyzej - to jest bezsensu i nawet nie ma co tu tlumaczyc dlaczego wink.gif
pag-r
Rozumiem, że nie zrozumiem odpowiedzi (bo nie dysponuję odpowiednim poziomem wiedzy;) skoro mój pomysł jest bez sensu. No nic dziękuję za odpowiedzi, temat można zamknąć/usunąć.
vincent vega
Twoja klasa musi udawać kolekcję (http://www.php.net/~helly/php/ext/spl/) i leniwie wykonywać zapytania do bazy danych - podobne podejście jest sotosowane w django.
  1. class LazyQuery implements Countable, ArrayAccess, Iterator {
  2. protected $results = null;
  3.  
  4. ... Twoje metody select table etc.
  5.  
  6. protected function lazyExecute() {
  7. // Wyrzuc wyjatek jezeli zapytanie nie jest w pelni zainicjalizowane np: nie wskazano tabeli
  8. if (is_null($this->results)) {
  9. $this->results = $this->executeQuery();
  10. }
  11. return $this->results;
  12. }
  13. // Countable
  14. public function count() {
  15. $this->lazyExecute();
  16. reutrn count($this->results);
  17. }
  18. // ArrayAccess
  19. public function offsetExists($offset) {
  20. $this->lazyExecute();
  21. return array_key_exists($offset, $this->results);
  22. }
  23.  
  24. ... Pozostale metody interfejsu ArrayAccess
  25.  
  26. // Iterator
  27. public function current() {
  28. $this->lazyExecute();
  29. return current($this->results);
  30. }
  31.  
  32. ... Pozostale metody interfejsu Iterator
  33. }
  34.  
  35. // Tego typu konstrukcje powinny wtedy zadzialac
  36. $rows = $query->from('tablename');
  37. count($rows);
  38. $rows[0];
  39. foreach ($rows as $row) {}
pag-r
@vincent vega: dzięki za podrzucenie pomysłu. Właśnie o taką implementację mi chodziło jako o przykład w jakim kierunku iść.
@nospor: jak to się ma do Twojej odpowiedzi "jest bez sensu bo jest bez sensu "?wink.gif.
Można? Można;).
nospor
Cytat
@nospor: jak to się ma do Twojej odpowiedzi "jest bez sensu bo jest bez sensu "?
No ale Ty chciales co innego.... Ty chciales, by na koncu tego:
$rows = $db->select('field')->from('tableName');
zostalo wykonane execute. A tu ci teraz podano rozwiazanie, bys execute wykonywal wtedy kiedy chcesz co notabene tez ci napisalem po czesci jakbys przeczytal smile.gif
pag-r
Ale właśnie o to mi chodziło.
Napisałem wyraźnie że chciałbym zarówno w
  1. $rows = $this->select('field')->from('tableName')->where('field = 1');

jak i
  1. $rows = $this->select('field')->from('tableName');

Mieć możliwość zrzucenia danych;)
No nic ważne że wiem jak do tego się dobraćsmile.gif
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.