Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: jak odczytać automatycznie nazwy pól obiektu?
Forum PHP.pl > Forum > PHP
jafet
Witam!

Czy ktoś z Was wie jak odczytać nazwy pól obiektu, jeśli były one ustawiane metodą __set?questionmark.gif
Zależy mi na takim oto rozwiązaniu: Mam klasę View(). Dla obiektu tej klasy w kontrolerze ustawiam różne dane. Ponieważ może być ich zmienna liczba, dlatego nie chcę towrzyć stałych pól np $model1, $model2, zamiast tego używam metody __set do ich ustawiania. Teraz w metodzie show() chcę odczytać nazwy tych pól i przypisać je do szablonu Smarty. Próbowałem to zrobić funkcją get_class_vars(get_class($this)) ale okazało się, że odczytuje ona tylko pola predefiniowane wcześniej w klasie. Pól ustawionych za pomocą __set nie widzi sad.gif
Jeśli ktoś ma jakiś pomysł będę wdzięcny.

Oto kod:
  1. <?php
  2.  
  3. abstract class View
  4. {
  5. public function __construct()
  6. {
  7.  
  8. }
  9.  
  10. public function __set($pole, $extra_model)
  11. {
  12. $this->$pole = $extra_model;
  13.  
  14. }
  15.  
  16. function __get($nazwa)
  17. {
  18. return $this->$nazwa;
  19. }
  20.  
  21. }
  22.  
  23. class HTMLView extends View
  24. {
  25. protected $smarty;
  26.  
  27. public function __construct()
  28. {
  29. parent::__construct();
  30. $this->smarty = new Smarty();
  31.  
  32. }
  33.  
  34. public function show()
  35. {
  36.  
  37. $fields = get_class_vars(get_class($this));
  38.  
  39. foreach ($fields as $name => $value) {
  40.  
  41. if ($name!='tamplate' && $name!='smarty')
  42. {
  43. $pole = "'".$name."'";
  44. $this->smarty->assign($pole, $name); 
  45. }
  46. }
  47.  
  48. $this->smarty->display($this->tamplate);
  49.  
  50. }
  51.  
  52. public function __call($name,$param)
  53. {
  54. echo "Próbowałeś wywołać metodę której nie ma ".$name;
  55. }
  56. }
  57. ?>



A oto przykład użycia w kontrolerze:
  1. <?php
  2.  
  3. $hview = new HTMLView();
  4. $hview->lista = $lista;
  5. $hview->tamplate="'".$this->tpl_prefix."list.tpl'";
  6. $hview->show();
  7.  
  8. ?>


Myslę, że sprawa jest warta zachodu, bo czy przypiszemy jedną listę czy 15, klasa HTMLView za nas robiłaby całe przypisanie do Smarty. Poza tym kod jest zupełnie niezależny od danych pobranych z modelu.
LBO
Hmmm, skoro nie działa poprzez domyślne funkcje to napisz własną (uprzedzam, że nigdy sie w ten temat nie zagłębiałem. Może istnieć inne, lepsze rozwiązanie). W metodzie _set stwórz tablicę i dodawaj pola obiektu do niej - pamietaj, koniecznie poprzez referencję. Potem wystarczy metoda zwracająca Tobie tą tablicę (+ predefiniowane pola obiektu).


P.S. Sprawdź czy nie odczytasz ich iterując poprzez obiekt (w ostatniej chwili pryszło mi to do głowy).
mike
Może tak:
  1. <?php
  2.  
  3. abstract class View
  4. {
  5. protected $arrVars = array();
  6.  
  7. public function __construct()
  8. {
  9. }
  10.  
  11. public function __set( $pole, $extra_model )
  12. {
  13. $this->$arrVars[ $pole ] = $extra_model;
  14. }
  15.  
  16. function __get($nazwa)
  17. {
  18. return ( empty( $this->arrVars[ $nazwa ] ) ) ? null : $this->arrVars[ $nazwa ];
  19. }
  20. }
  21.  
  22. class HTMLView extends View
  23. {
  24. protected $smarty;
  25.  
  26. public function __construct()
  27. {
  28. }
  29.  
  30. public function show()
  31. {
  32. //... tu dopasuj sobie do swoich potrzeb
  33. foreach( $this->arrVars as $strVarName => $mixVarValue )
  34. {
  35. $this->smarty->assign( $strVarName, $mixVarValue ); 
  36. }
  37. //...
  38. }
  39. }
  40.  
  41. ?>

:?:
jafet
Dzięki wielkie za sugestie Wasze. Poszedłem tym właśnie tropem, tylko trochę dostosowałem rozwiązanie mike_mech. Jakby ktoś potrzebował to oto działający kod:
  1. <?php
  2.  
  3. abstract class View
  4. {
  5. protected $var_names = array();
  6.  
  7. public function __construct()
  8. {
  9.  
  10. }
  11.  
  12. public function __set($pole, $extra_model)
  13. {
  14. if ($pole=='tamplate')
  15. $this->$pole = $extra_model;
  16. else
  17. $this->var_names[$pole] = $extra_model;
  18. }
  19.  
  20. public function show() 
  21. {
  22.  
  23. }
  24.  
  25.  
  26. }
  27.  
  28. class HTMLView extends View
  29. {
  30. protected $smarty;
  31.  
  32. public function __construct()
  33. {
  34. parent::__construct();
  35. $this->smarty = new Smarty();
  36.  
  37. }
  38.  
  39. public function show()
  40. {
  41.  
  42. foreach ($this->var_names as $name => $value) {
  43.  
  44. if ($name!='tamplate' && $name!='smarty')
  45. {
  46. $pole = $name.'';
  47.  
  48. $this->smarty->assign($pole, $value); 
  49. }
  50. }
  51.  
  52. $this->smarty->display($this->tamplate);
  53.  
  54. }
  55.  
  56. public function __call($name,$param)
  57. {
  58. echo "Próbowałeś wywołać metodę której nie ma ".$name;
  59. }
  60. }
  61.  
  62. ?>


Pozdrawiam
LBO
HA! Miałem rację, poprzez iterację są widoczne również dynamiczne pola klasy.
Przeanalizujcie sobie ten przykład.
  1. <?php
  2. class Example {
  3. public $publicParent = 'publicParent';
  4. private $private1Parent = 'privateParent';
  5. protected $protectedParent = 'protectedParent';
  6.  
  7. public function __set($name, $value) {
  8. $this->$name = $value;
  9. }
  10.  
  11. public function __get($name) {
  12. return $this->$name;
  13. }
  14. }
  15.  
  16. class ShowExample extends Example {
  17. public $publicChild = 'publicChild';
  18. private $private1Child = 'privateChild';
  19. protected $protectedChild = 'protectedChild';
  20.  
  21. public function show() {
  22. foreach($this as $name => $value) {
  23. print $name.' => '.$value.'<br />';
  24. }
  25. }
  26. }
  27.  
  28. function iterateOverObject($obj) {
  29. foreach($obj as $name => $value) {
  30. print $name.' => '.$value.'<br />';
  31. };
  32. };
  33.  
  34. $example = new ShowExample();
  35. $example->name_01 = 'value 01';
  36. $example->name_02 = 'value 02';
  37. $example->name_03 = 'value 03';
  38. print('Iteracja poprzez metode klasy <br />');
  39. $example->show();
  40. print('Iteracja poprzez funckjк zewnкtrzna <br />');
  41. iterateOverObject($example);
  42. ?>

a to jest output:
Kod
Iteracja poprzez metode klasy
  publicChild => publicChild
  private1Child => privateChild
  protectedChild => protectedChild
  publicParent => publicParent
  protectedParent => protectedParent
  name_01 => value 01
  name_02 => value 02
  name_03 => value 03

Iteracja poprzez funckję zewnętrzna
  publicChild => publicChild
  publicParent => publicParent
  name_01 => value 01
  name_02 => value 02
  name_03 => value 03


Oj, dopiero teraz zauważyłem ten warunek:
Cytat
Czy ktoś z Was wie jak odczytać nazwy pól obiektu, jeśli były one ustawiane metodą __set?questionmark.gif
. Więc to co napisałem, raczej się tobie nie przyda ~jafet.
060156
Tutaj masz przyklad:
  1. <?php
  2.  
  3. foreach(get_object_vars($object) as $attribute=>$value) {
  4. }
  5.  
  6. ?>
LBO
To zadziała dokładnie tak samo jak:
  1. <?php
  2.  
  3. foreach($object as $attribute => $value) {
  4. //code
  5. }
  6.  
  7. ?>


edit: Co do pytania założyciela tematu:
Cytat
Czy ktoś z Was wie jak odczytać nazwy pól obiektu, jeśli były one ustawiane metodą __set?

~mike_mech, nie trzeba tworzyc dodatkowej tablicy, by osiągnąć ten efekt. Oto kod:
  1. <?php
  2. //zwraca tablicę tylko z dynamicznymi (stworzonymi
  3. //za pomocą metody _set) polami obiektu $obj
  4. function showDynamicAttributes($obj) {
  5. return array_diff_assoc(get_object_vars($obj), get_class_vars(get_class($obj)));
  6. }
  7.  
  8. ?>
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.