Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [OOP] Dostęp do danych parametru w klasie - dyskusja, Traktować dane jako obiekty, a może zastosować iterator ArrayAccess...
Athlan
post
Post #1





Grupa: Developerzy
Postów: 823
Pomógł: 12
Dołączył: 18.12.2005

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


W tytule tematu napisałem "dyskusja". Dziś nie przychodzę na forum z pyaniem, ale z prośbą o wyrązenie swoich opinii na możliwości jakie daje nam OOP.

Przypuśćmy, że mamy do napisania klasę, która będzie importować dane w formie tablicy i je udostępniać (rzucam przykładem, aby zobrazowac jakie możliwości daje OOP).

Przypadek nr 1:

  1. <?php
  2. final class MyConfigObject
  3. {
  4. private $_aParametrs = array();
  5.  
  6. public function __construct(array $aFields = array())
  7. {
  8. $this->_aParametrs = $aFields;
  9. }
  10.  
  11. public function __get($sParam)
  12. {
  13. if(!isset($this->_aParametrs[$sParam]))
  14. return null;
  15.  
  16. if(is_array($this->_aParametrs[$sParam]))
  17. return new MyConfigObject($this->_aParametrs[$sParam]);
  18. else
  19. return $this->_aParametrs[$sParam];
  20. }
  21.  
  22. public function __set($sParam, $mValue)
  23. {
  24. return $this->_aParametrs[$sParam] = $mValue;
  25. }
  26. }
  27. ?>


Użycie przypadka 1:

  1. <?php
  2. $aSampleArray = array(
  3. 'field1' => 'value1',
  4. 'field2' => array('fieldarray1' => 'valuearray1'),
  5. 'field3' => array('fieldarray2' => array('fieldarray3' => array('fieldarray4' => 'valuearray4'))),
  6. );
  7.  
  8. $oMyConfig = new MyConfigObject($aSampleArray);
  9.  
  10. echo $oMyConfig->field1; // value1
  11. echo $oMyConfig->field2->fieldarray1; // valuearray1
  12. echo $oMyConfig->field3->fieldarray2->fieldarray3->fieldarray4 // valuearray4
  13. ?>


Plusy:
  • traktujemy elementy tablicy jako obiekty, co jest zgodne z teorią OOP
  • banalny wręcz dostęp do danych
Minusy:
  • nie ma możliwości wykonania operacji for(), foreach() na elementach tablicy (jest obiektem)
Przykład numer 2:

  1. <?php
  2. final class MyConfigArray implements ArrayAccess
  3. {
  4. private $_aParametrs = array();
  5.  
  6. public function __construct(array $aFields = array())
  7. {
  8. $this->_aParametrs = $aFields;
  9. }
  10.  
  11. public function offsetGet($sParam)
  12. {
  13. if(!isset($this->_aParametrs[$sParam]))
  14. return null;
  15.  
  16. if(is_array($this->_aParametrs[$sParam]))
  17. return new MyConfigArray($this->_aParametrs[$sParam]);
  18. else
  19. return $this->_aParametrs[$sParam];
  20. }
  21.  
  22. public function offsetSet($sParam, $mValue)
  23. {
  24. return $this->_aParametrs[$sParam] = $mValue;
  25. }
  26.  
  27. public function offsetExists($sParam)
  28. {
  29. return (isset($this->_aParametrs[$sParam]) ? true : false);
  30. }
  31.  
  32. public function offsetUnset($sParam)
  33. {
  34. unset($this->_aParametrs[$sParam]);
  35. }
  36. }
  37. ?>


Przykład uzycia sposobu nr 2:
  1. <?php
  2. $aSampleArray = array(
  3. 'field1' => 'value1',
  4. 'field2' => array('fieldarray1' => 'valuearray1'),
  5. 'field3' => array('fieldarray2' => array('fieldarray3' => array('fieldarray4' => 'valuearray4'))),
  6. );
  7.  
  8. $oMyConfig = new MyConfigArray($aSampleArray);
  9.  
  10. echo $oMyConfig['field1']; // value1
  11. echo $oMyConfig['field2']['fieldarray1']; // valuearray1
  12. echo $oMyConfig['field3']['fieldarray2']['fieldarray3']['fieldarray4']; // valuearray4
  13. ?>


Dzięki interfejsowi ArrayAcess otrzymujemy dostęp do danych obiektu jak do zwykłej tablicy, dlatego...

Plusy:
  • Możemy posłużyć się danymi w for(), foreach()
  • staroświedzki sposób dostępu z php 4
  • nie traktujemy danych jako obiekty (przeciwne teorii OOP)
Przykład numer 1 zastosowany jest na przykład w moim frameworku:
http://framework.vgroup.pl/expose-9a722aa0...965ef22bc4d.htm

Przykład drugi ma dobrego plusa: można użyć go jako normalnej tablicy, poslugując się chociażby for(), foreach(), count() itd.

Natomiast zastanawia mnie jeszcze jedna rzecz, a mianowicie połączenie tych dwóch sposobów dostępu do danych... wyszłaby ciekawa mieszanka, wartoby było spróbować.

Kwestię opinii pozostawiam Wam, być może nie dostrzegłem kolejnych plusów i minusów obu sposobów, być może niektóre z przedstawionych są błędne, zapraszam do dyskusji smile.gif

Pozdrawiam, Athlan smile.gif

Ten post edytował Athlan 25.01.2007, 15:55:36


--------------------
Portfolio: Vgroup.pl | athlan.pl | Test.php.pl - sprawdź się z wiedzy o PHP i ułóż własne pytania!
Pomogłem? Kliknij pod postem.
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 8)
ikioloak
post
Post #2





Grupa: Zarejestrowani
Postów: 416
Pomógł: 0
Dołączył: 8.01.2004

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


wow nie wiedzialem ze jest interfejs (chyba o to ci chodzilo piszac iterator) ArrayAccess. W 1. przykladzie mozesz wlasnie zrobic tak aby klasa implementowala interfejs Iterator, dzieki czemu bedziesz mogl ja wykorzystywac w instrukcjach foreach.
Go to the top of the page
+Quote Post
mysz
post
Post #3





Grupa: Zarejestrowani
Postów: 81
Pomógł: 0
Dołączył: 26.08.2006
Skąd: Szczecin

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


urzenia.net/298/obiekt-jako-tablica-wprowadzenie-do-spl/


--------------------
urzenia.net
Go to the top of the page
+Quote Post
Prph
post
Post #4





Grupa: Zarejestrowani
Postów: 338
Pomógł: 2
Dołączył: 4.03.2006
Skąd: Łódź

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


Wszystko wydaje się piękne, ale w przypadku iteratora, spróbuj:

  1. <?php
  2. $mojObiekt->pierwszy->drugi->trzeci->czwarty;
  3. ?>


gdzie "pierwszy" już nie istnieje. php wywali błędy pomimo zastosowania isset (przynajmniej tak było, jak ja o tym pisałem).

Ogólnie nie przepadam za tymi interfejsami. Podoba mi się natomiast rozwiązanie typu:

  1. <?php
  2. $obiekt->get('pierwszy', 'drugi', 'trzeci');
  3. ?>



Jeżeli myle się co do 1. rozwiązania - proszę mnie wyprowadzić z błędu winksmiley.jpg

Adrian.
Go to the top of the page
+Quote Post
NuLL
post
Post #5





Grupa: Zarejestrowani
Postów: 2 262
Pomógł: 21
Dołączył: 3.05.2004
Skąd: Sopot, Krakow, W-wa

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


Nie mylisz sie smile.gif
  1. <?php
  2. if($object->has('costam'))
  3. {
  4. ble ble
  5. }
  6. ?>

Tak powinno wygladac sprawdzanie czy cos jest. Pisanie klas kolekcyjnych bez metod typu has czy contains jest bledem poprostu.

Pozatym kolega Athlan powinien sie dowiedziec co to Iterator zamiast rozwazac rozne rozwiazania ze tak powiem winksmiley.jpg


--------------------
Javascript, Coffeescript, Node.js, Mongo, CouchDb, chmury, workery & inne bajery - zycie jest zbyt krotkie aby miec nudna prace :)
Go to the top of the page
+Quote Post
Athlan
post
Post #6





Grupa: Developerzy
Postów: 823
Pomógł: 12
Dołączył: 18.12.2005

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


@NuLL, czym jest Iterator oczywiście wiem smile.gif Przesłowiłem się smile.gif Poza tym to nie jest iterator, tylko interfejs (przynajmniej tak jest napisane w książce Sebastiana Bergmana) smile.gif Chodzi mi tylko i wyłącznie dostęp do danych...

@Prph: do przykładu numer 1:
  1. <?php
  2. $aSampleArray = array(
  3. 'field1' => 'value1',
  4. 'field2' => array('fieldarray1' => 'valuearray1'),
  5. 'field3' => array('fieldarray2' => array('fieldarray3' => array('fieldarray4' => 'valuearray4'))),
  6. );
  7.  
  8. $oMyConfig = new MyConfigObject($aSampleArray);
  9.  
  10. var_dump( $oMyConfig->nie_istniejacy_klucz->fieldarray2->fieldarray3->fieldarray4 );
  11. ?>

zwóciło NULL... worriedsmiley.gif nie ma żadnego błędu...

Idę sobie do szkoły a tu: blink.gif wymyśliłem coś:

  1. <?php
  2.  
  3. final class MyConfigMulti implements ArrayAccess
  4. {
  5. private $_aParametrs = array();
  6.  
  7. public function __construct(array $aFields = array())
  8. {
  9. $this->_aParametrs = $aFields;
  10. }
  11.  
  12. public function __get($sParam)
  13. {
  14. return $this->_getParam($sParam);
  15. }
  16.  
  17. public function offsetGet($sParam)
  18. {
  19. return $this->_getParam($sParam);
  20. }
  21.  
  22. public function __set($sParam, $mValue)
  23. {
  24. return $this->_aParametrs[$sParam] = $mValue;
  25. }
  26.  
  27. public function offsetSet($sParam, $mValue)
  28. {
  29. return $this->_aParametrs[$sParam] = $mValue;
  30. }
  31.  
  32. public function offsetExists($sParam)
  33. {
  34. return (isset($this->_aParametrs[$sParam]) ? true : false);
  35. }
  36.  
  37. public function offsetUnset($sParam)
  38. {
  39. unset($this->_aParametrs[$sParam]);
  40. }
  41.  
  42. private function _getParam($sParam)
  43. {
  44. if(!isset($this->_aParametrs[$sParam]))
  45. return null;
  46.  
  47. if(is_array($this->_aParametrs[$sParam]))
  48. return new self($this->_aParametrs[$sParam]);
  49. else
  50. return $this->_aParametrs[$sParam];
  51. }
  52. }
  53.  
  54. ?>


Dostęp:

  1. <?php
  2. $aSampleArray = array(
  3. 'field1' => 'value1',
  4. 'field2' => array('fieldarray1' => 'valuearray1'),
  5. 'field3' => array('fieldarray2' => array('fieldarray3' => array('fieldarray4' => 'valuearray4'))),
  6. );
  7.  
  8. $oMyConfig = new MyConfigMulti($aSampleArray);
  9.  
  10. echo $oMyConfig['field1']; // value1
  11. echo $oMyConfig['field2']['fieldarray1']; // valuearray1
  12. echo $oMyConfig['field3']['fieldarray2']['fieldarray3']['fieldarray4']; // valuearray4
  13.  
  14. echo $oMyConfig->field1; // value1
  15. echo $oMyConfig->field2->fieldarray1; // valuearray1
  16. echo $oMyConfig->field3->fieldarray2->fieldarray3->fieldarray4; // valuearray4
  17. ?>


Tak tylko eksperymentuje, narazie nie wkładam w to wiele wagi, nie używam w projektach... stworzyłem na swoim poligonie śmieciatych, czasem przydatnych skryptów smile.gif

Co to tym myślicie? dry.gif Pytam TYLKO I WYŁĄCZNIE o mozliwości zastosowania, wygodę użycia itp. Wpadło mi do głowy to napislaem tongue.gif

Pozdrawiam, Athlan smile.gif

-- EDIT ---

Aaaaaa, @Prph, chodzi Ci o isset(), czy zmienna została zadeklarowana. W prypadku, który Ci podałem wynika że zwracamy NULL, co nie jest poprawne. Zgadzam się z Tobą i @NuLL'em, metoda has() jest jak najbardziej potrzebna... można ją owszem dodać do obu klas, jednak interesuje mnie sam dostęp do danych, wykonywanie operacji...

Ten post edytował Athlan 25.01.2007, 16:30:05


--------------------
Portfolio: Vgroup.pl | athlan.pl | Test.php.pl - sprawdź się z wiedzy o PHP i ułóż własne pytania!
Pomogłem? Kliknij pod postem.
Go to the top of the page
+Quote Post
LEW21
post
Post #7





Grupa: Zarejestrowani
Postów: 20
Pomógł: 0
Dołączył: 31.01.2007

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


Athlan, Iterator != Interfejs smile.gif Iterator to jeden z wbudowanych w php interfejsów. Więcej informacji jest na http://php.net/~helly/php/ext/spl/

PS. Co do przykładu użycia Iteratora - zerkinij do mojej klasy php SimpleDB (wysłanej na konkurs). Zastosowałem w niej i Iterator, i ArrayAccess, i zwykłą obiektową metodę dostępu do danych.


--------------------
Przyjazne użytkownikom polskie wsparcie phpBB3 - phpBB3.PL
Go to the top of the page
+Quote Post
Athlan
post
Post #8





Grupa: Developerzy
Postów: 823
Pomógł: 12
Dołączył: 18.12.2005

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


Cytat
Athlan, Iterator != Interfejs

Wiem smile.gif

Na wstępie chciałbym powitać wszystkich forumowiczów, po długim okresie nieobecności z powodu bana smile.gif (pozdrawiam administrację tongue.gif )

Temat aktualny, większość problemów rozwiązanych poprzez użycie metody magicznej __isset(), więc po co has() ?

Kod klasy (prototyp, przyklad):

  1. <?php
  2.  
  3. class Rapide_Parametrs implements ArrayAccess
  4. {
  5. private $_aParametrs = array();
  6.  
  7. public function __construct(array $aFields = array())
  8. {
  9. $this->_aParametrs = $aFields;
  10. }
  11.  
  12. public function __get($sParam)
  13. {
  14. if(!isset($this->_aParametrs[$sParam]))
  15. return null;
  16.  
  17. if(is_array($this->_aParametrs[$sParam]))
  18. return new self($this->_aParametrs[$sParam]);
  19. else
  20. return $this->_aParametrs[$sParam];
  21. }
  22.  
  23. public function __set($sParam, $mValue)
  24. {
  25. return $this->_aParametrs[$sParam] = $mValue;
  26. }
  27.  
  28. public function __isset($sParam)
  29. {
  30. return (bool)isset($this->_aParametrs[$sParam]);
  31. }
  32.  
  33. public function __unset($sParam)
  34. {
  35. unset($this->_aParametrs[$sParam]);
  36. }
  37.  
  38. public function offsetGet($sParam)
  39. {
  40. return $this->__get($sParam);
  41. }
  42.  
  43. public function offsetSet($sParam, $mValue)
  44. {
  45. return $this->__set($sParam, $mValue);
  46. }
  47.  
  48. public function offsetExists($sParam)
  49. {
  50. return $this->__isset($sParam);
  51. }
  52.  
  53. public function offsetUnset($sParam)
  54. {
  55. $this->__unset($sParam);
  56. }
  57. }
  58.  
  59. ?>


Uzycie:

  1. <?php
  2. $aSampleArray = array(
  3. 'field1' => 'value1',
  4. 'field2' => array('fieldarray1' => 'valuearray1'),
  5. 'field3' => array('fieldarray2' => array('fieldarray3' => array('fieldarray4' => 'valuearray4'))),
  6. );
  7.  
  8. $oMyConfig = new Rapide_Parametrs($aSampleArray);
  9.  
  10. // obiekcik
  11. var_dump( $oMyConfig->field1 ); // value1
  12. var_dump( $oMyConfig->field2->fieldarray1 ); // valuearray1
  13. var_dump( $oMyConfig->field3->fieldarray2->fieldarray3->fieldarray4 ); // valuearray4
  14. var_dump( $oMyConfig->sdhcbdbc->sxasxasxas->sxasxasx->fieldarray2->fieldarray3->fieldarray4 ); // null
  15. var_dump( isset($oMyConfig->sdhcbdbc->fieldarray2->fieldarray3->fieldarray4) ); // false
  16. unset($oMyConfig->field3->fieldarray2->fieldarray3->fieldarray4); // nie dziala...
  17. var_dump( $oMyConfig->field3->fieldarray2->fieldarray3->fieldarray4 ); // null
  18.  
  19. // a teraz tabliczka
  20. var_dump( $oMyConfig['field1'] ); // value1
  21. var_dump( $oMyConfig['field2']['fieldarray1'] ); // valuearray1
  22. var_dump( $oMyConfig['field3']['fieldarray2']['fieldarray3']['fieldarray4'] ); // valuearray4
  23. var_dump( $oMyConfig['asxasxasxs']['sss']['vfdvdfvdf']['fieldarray2']['fieldarray3']['fieldarray4'] ); // null
  24. var_dump( isset($oMyConfig['asxasxasxs']['sss']['vfdvdfvdf']['fieldarray2']['fieldarray3']['fieldarray4'] ) ); // null
  25. unset( $oMyConfig['field3']['fieldarray2']['fieldarray3']['fieldarray4'] ); // nie dziala ...
  26. var_dump( $oMyConfig['field3']['fieldarray2']['fieldarray3']['fieldarray4'] ); // valuearray4
  27. ?>


Problem w linii:
unset($oMyConfig->field3->fieldarray2->fieldarray3->fieldarray4);
tak samo przy dostępie w ArrayAccess... dlaczego? Usówamy obiekt pochodny z tablicy stworzony przez __get(), a nie element tablicy. Póki co nie mam pojęcia jak to wykonać. Jeżeli macie jakieś pomysły to śmiało smile.gif

Pozdrawiam, Athlan smile.gif


--------------------
Portfolio: Vgroup.pl | athlan.pl | Test.php.pl - sprawdź się z wiedzy o PHP i ułóż własne pytania!
Pomogłem? Kliknij pod postem.
Go to the top of the page
+Quote Post
Hacker
post
Post #9





Grupa: Zarejestrowani
Postów: 225
Pomógł: 0
Dołączył: 1.11.2005

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


Moim zdaniem nie twórz za każdym getem nowych obiektów przechowuj zagnieżdżenia w tabeli
wystarczy wtedy sprawdzanie w __set i konstruktorze i tam tworzenie obiektów


--------------------
(\.../)This is Bunny
(O.o)Copy Bunny into your signature to help him...
(> <)...on his way to world domination
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: 20.08.2025 - 06:32