Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Rozszerzenie klasy, Czyli co i jak...
Fifi209
post
Post #1





Grupa: Zarejestrowani
Postów: 4 655
Pomógł: 556
Dołączył: 17.03.2009
Skąd: Katowice

Ostrzeżenie: (0%)
-----


Witam!

Potrzebuję podzielić widok, na kilka klas. Dokładniej chcę mieć główny widok i klasy które rozszerzą jego możliwości.

Nie byłoby problemu, bo mógłbym nawet dziedziczyć tylko, że potrzebuję użyć np. 3-4 rozszerzeń naraz.

Przykłady rozszerzeń:
- Klasa obsługująca szablony (parsowanie etc.)
- Klasa parsująca bb-code
- Klasa tworząca formularze

Sam wymyśliłem coś takiego:

Klasa widok, ma metodę:
  1. public function _load($name) {
  2. if ($this->$name) {
  3. return $this->$name;
  4. }else{
  5. $temp = __CLASS__ .'_'. $name;
  6. if (file_exists('modules/'.$temp.'.php')) {
  7. include_once('modules/'.$temp.'.php');
  8. return $this->$name = new $temp;
  9. }else{
  10. return false;
  11. }
  12. }
  13. }


Problem polega na tym, że używanie tak wczytanego modułu jest niewygodne, bo muszę robić to np. tak:
  1. $view->template->metoda();


Od razu tutaj zaznaczę, że mam magiczną metodę __get() dlatego odwołuję się poprzez $view->template.

Co w tym niewygodnego? Muszę wszystko zwracać returnami, bo inaczej nic w widoku nie zapiszę.

Dokładniej:

  1.  
  2. $view = view::create(); // Zwraca obiekt, wzorzec singleton
  3. $view->_load('template');
  4.  
  5. // działania na template np.
  6. $view->template->_loadFile('tpl/index.tpl');
  7.  
  8. // Powiedzmy podmieniamy co mamy podmienić w szablonie
  9. $podmiana = array('title' => 'test', 'content' => 'testy');
  10.  
  11. foreach ($podmiana as $key => $value) {
  12. $view->template->add($key, $value);
  13. }
  14.  
  15. // zapis wyniku działania modułu template
  16. $view->save($view->template); // i to mi się nie podoba, dałem sobie


To co mi się nie podoba, działa akurat na zasadzie wywołania __toString, który uruchamia parser template.
Z template jest najmniejszy problem, gorzej z robieniem formów... Gdzie np. każdego inputa muszę zapisać do zmiennej i potem $view->save($zmiennaZinputem)

Jak za słabo objaśniłem to czekam na pytania. haha.gif


--------------------
Zainteresowania: C#, PHP, JS, SQL, AJAX, XML, C dla AVR
Chętnie pomogę, lecz zanim napiszesz: Wujek Google , Manual PHP
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 10)
-=Peter=-
post
Post #2





Grupa: Zarejestrowani
Postów: 304
Pomógł: 51
Dołączył: 4.02.2005
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Nie wiem czy dobrze zrozumiałem Twój problem, ale jeśli w aplikacji istnieje "zapach" wielodziedziczenia to dekorator powinien dać radę ;] Ewentualnie możesz zrobić "złożony" widok (Composite), do którego dodajesz te widoki podrzędne o których mówisz, a widok główny deleguje zadania kolejno do każdego z widoków podrzędnych i składa wynik.

Ten post edytował -=Peter=- 10.08.2009, 12:20:29


--------------------
Go to the top of the page
+Quote Post
Fifi209
post
Post #3





Grupa: Zarejestrowani
Postów: 4 655
Pomógł: 556
Dołączył: 17.03.2009
Skąd: Katowice

Ostrzeżenie: (0%)
-----


Cytat(-=Peter=- @ 10.08.2009, 12:19:43 ) *
Nie wiem czy dobrze zrozumiałem Twój problem, ale jeśli w aplikacji istnieje "zapach" wielodziedziczenia to dekorator powinien dać radę ;]

Tutaj nie ma dziedziczenia, napisałem że gdyby chodziło o jeden moduł rozszerzający naraz to bym dziedziczył, w przeciwnym wypadku (tym) nie mogę.

Cytat(-=Peter=- @ 10.08.2009, 12:19:43 ) *
Ewentualnie możesz zrobić "złożony" widok (Composite), do którego dodajesz te widoki podrzędne o których mówisz, a widok główny deleguje zadania kolejno do każdego z widoków podrzędnych i składa wynik.

Nie wiem czy dobrze zrozumiałem, ale właśnie do głównego widoku ładuję te moduły rozszerzające czy jak to nazwałeś widoki podrzędne.


--------------------
Zainteresowania: C#, PHP, JS, SQL, AJAX, XML, C dla AVR
Chętnie pomogę, lecz zanim napiszesz: Wujek Google , Manual PHP
Go to the top of the page
+Quote Post
erix
post
Post #4





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




Nie wiem, czy u Ciebie nie byłby dobry wzorzec Adapter.

Cytat
Jak za słabo objaśniłem to czekam na pytania.

Trochę nie jarzę, jak chcesz w ogóle to wszystko osiągnąć - żeby samo wczytywało wstawki i automatycznie je wykonywało?


--------------------

ZCE :: Pisząc PW załączaj LINK DO TEMATU i TYLKO w sprawach moderacji :: jakiś błąd - a TREŚĆ BŁĘDU? :: nie ponaglaj z odpowiedzią via PW!
Go to the top of the page
+Quote Post
Fifi209
post
Post #5





Grupa: Zarejestrowani
Postów: 4 655
Pomógł: 556
Dołączył: 17.03.2009
Skąd: Katowice

Ostrzeżenie: (0%)
-----


Cytat(erix @ 10.08.2009, 13:16:43 ) *
Trochę nie jarzę, jak chcesz w ogóle to wszystko osiągnąć - żeby samo wczytywało wstawki i automatycznie je wykonywało?


Chodzi mi o to, abym mógł w prosty sposób rozwiązać "komunikację" głównego widoku z modułami rozszerzającymi.

Przykładowo moduł do form, powiedzmy tworzenie inputa:

  1.  
  2. $params = array('type' => 'text', 'name' => 'test');
  3.  
  4. $input = $view->form->createInput($params);
  5.  
  6. // i muszę go zapisywać tak:
  7. $view->save($input);
  8.  


Chodzi mi o to, aby po wywołaniu $view->form->createInput była jakby "automatycznie" wywoływana $view->save(), abym nie musiał tworzyć kolejnej zmiennej w tym wypadku $input.

Bo robi się bałagan jak robię np. 3 inputy (login, hasło, submit)

Jednym słowem wszystko jest jakieś niewygodne.

Jak trzeba to pokażę moje testowe/przejściowe rozwiązanie, napisane na kolanie.


--------------------
Zainteresowania: C#, PHP, JS, SQL, AJAX, XML, C dla AVR
Chętnie pomogę, lecz zanim napiszesz: Wujek Google , Manual PHP
Go to the top of the page
+Quote Post
erix
post
Post #6





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




Cytat
Chodzi mi o to, aby po wywołaniu $view->form->createInput była jakby "automatycznie" wywoływana $view->save(), abym nie musiał tworzyć kolejnej zmiennej w tym wypadku $input.

Hmm, to może zrób wg tego:

  1. // konstruktor wstawki
  2. $klasa = new klasa;
  3. $klasa->view = $this;

i potem wewnątrz tamtej klasy wywołujesz, co trzeba.


--------------------

ZCE :: Pisząc PW załączaj LINK DO TEMATU i TYLKO w sprawach moderacji :: jakiś błąd - a TREŚĆ BŁĘDU? :: nie ponaglaj z odpowiedzią via PW!
Go to the top of the page
+Quote Post
skowron-line
post
Post #7





Grupa: Zarejestrowani
Postów: 4 340
Pomógł: 542
Dołączył: 15.01.2006
Skąd: Olsztyn/Warszawa

Ostrzeżenie: (0%)
-----


Nie jestem ekspertem w OOP i może napisze niezłą głupotę ale czy __call by ci nie pomogło questionmark.gif
__call


--------------------
I'm so fast that last night I turned off the light switch in my hotel room and was in bed before the room was dark - Muhammad Ali.
Peg jeżeli chcesz uprawiać sex to dzieci muszą wyjść, a jeżeli chcesz żeby był dobry ty też musisz wyjść - Al Bundy.

QueryBuilder, Mootools.net, bbcradio1::MistaJam
http://www.phpbench.com/
Go to the top of the page
+Quote Post
Fifi209
post
Post #8





Grupa: Zarejestrowani
Postów: 4 655
Pomógł: 556
Dołączył: 17.03.2009
Skąd: Katowice

Ostrzeżenie: (0%)
-----


Chyba lepiej pokaże moje rozwiązanie na kolanie pisane:

Klasa view (główna) do niej "ładuję" moduły
  1. <?php
  2.  
  3. class view {
  4.  
  5. protected $content;
  6. private $modules;
  7.  
  8. private function __construct() {}
  9.  
  10. public function __toString() {
  11. if ($this->content) {
  12. return $this->content;
  13. }else{
  14. return 'It\'s empty!';
  15. }
  16. }
  17.  
  18. public function __get($name) {
  19. if ($this->modules[$name]) {
  20. return $this->modules[$name];
  21. }else{
  22. return false;
  23. }
  24. }
  25.  
  26. static public function create() {
  27. static $handle;
  28. if (!isset($handle)) {
  29. $handle = new view();
  30. }
  31. return $handle;
  32. }
  33.  
  34. public function _load($name) {
  35. if ($this->$name) {
  36. return $this->$name;
  37. }else{
  38. $temp = __CLASS__ .'_'. $name;
  39. if (file_exists('modules/'.$temp.'.php')) {
  40. include_once('modules/'.$temp.'.php');
  41. return $this->$name = new $temp;
  42. }else{
  43. return false;
  44. }
  45. }
  46. }
  47.  
  48. public function save($text) {
  49. return $this->content .= $text;
  50. }
  51.  
  52. public function view() {
  53. if ($this->content) {
  54. return $this->content;
  55. }else{
  56. return false;
  57. }
  58. }
  59.  
  60. }
  61.  
  62. ?>


Przykładowy moduł:
  1. <?php
  2.  
  3. class view_template {
  4.  
  5. private $vars;
  6. private $values;
  7. private $content;
  8.  
  9. public function __toString() {
  10. return $this->parse();
  11. }
  12.  
  13. public function add($var, $value) {
  14. $this->vars[] = $var;
  15. $this->values[] = $value;
  16. return true;
  17. }
  18.  
  19. public function _load($text) {
  20. $this->content = $text;
  21. }
  22.  
  23. public function parse() {
  24. if ((is_array($this->vars)) && (is_array($this->values))) {
  25. return str_replace($this->vars, $this->values, $this->content);
  26. }else{
  27. return 'Error';
  28. }
  29. }
  30.  
  31. }
  32.  
  33. ?>


Mam nadzieję, że to mniej więcej rozjaśni mój problem. ;d


--------------------
Zainteresowania: C#, PHP, JS, SQL, AJAX, XML, C dla AVR
Chętnie pomogę, lecz zanim napiszesz: Wujek Google , Manual PHP
Go to the top of the page
+Quote Post
megawebmaster
post
Post #9





Grupa: Zarejestrowani
Postów: 143
Pomógł: 17
Dołączył: 8.11.2008
Skąd: Libiąż

Ostrzeżenie: (0%)
-----


I jak masz zamiar tego użyć? Bo mimo, że się wgłębiłem, to nie mogę znaleźć się w Twoim kodzie... Pokaż przykładowy kod użycia proszę.

BTW. Od tego są tablice asocjacyjne, żeby nie robić takich diabełków jak to:
  1. public function add($var, $value) {
  2. $this->vars[] = $var;
  3. $this->values[] = $value;
  4. return true;
  5. }


tylko uprościć sobie:

  1. public function add($var, $value) {
  2. $this->vars[$var] = $value;
  3. return true;
  4. }


EDIT: Potem sobie korzystasz z array_keys()

Ten post edytował megawebmaster 15.08.2009, 22:18:27
Go to the top of the page
+Quote Post
Fifi209
post
Post #10





Grupa: Zarejestrowani
Postów: 4 655
Pomógł: 556
Dołączył: 17.03.2009
Skąd: Katowice

Ostrzeżenie: (0%)
-----


Cytat(megawebmaster @ 15.08.2009, 22:17:48 ) *
I jak masz zamiar tego użyć? Bo mimo, że się wgłębiłem, to nie mogę znaleźć się w Twoim kodzie... Pokaż przykładowy kod użycia proszę.

Masz w pierwszym poście...
Cytat(megawebmaster @ 15.08.2009, 22:17:48 ) *
BTW. Od tego są tablice asocjacyjne, żeby nie robić takich diabełków jak to:

Jak już wspomniałem kod jest pisany na kolanie, tylko w celach "testowych". (chciałem zobaczyć jak to będzie działało)


--------------------
Zainteresowania: C#, PHP, JS, SQL, AJAX, XML, C dla AVR
Chętnie pomogę, lecz zanim napiszesz: Wujek Google , Manual PHP
Go to the top of the page
+Quote Post
megawebmaster
post
Post #11





Grupa: Zarejestrowani
Postów: 143
Pomógł: 17
Dołączył: 8.11.2008
Skąd: Libiąż

Ostrzeżenie: (0%)
-----


No to najprostszym rozwiązaniem jest przekazanie do obiektu view_template przy ładowaniu samego siebie ($this) i w ten sposób uzyskasz dostęp do metod klasy view. Dzięki temu możesz sobie dodać zapisywanie, albo nawet bezpośrednie dodawanie do zmiennej $content klasy view w metodach dołączonych. To takie najprostsze rozwiązanie. Inne rozwiązanie to zrobienie to tak jak napisał ktoś wcześniej - wzorzec adapter - i ładowanie modułów, ale ich obsługa bezpośrednio w klasie view. To tyle wymyśliłem na kolanie.

P.S. Ewentualnie w obiektach modułów można wywołać w konstruktorze modułu view::create() i pobrać instancję klasy view.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 19.08.2025 - 19:50