Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Obsługa właściwości tablicowych w klasie z użyciem "metod magicznych"
Gieroslawski
post 3.11.2017, 00:16:45
Post #1





Grupa: Zarejestrowani
Postów: 2
Pomógł: 0
Dołączył: 2.11.2017

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


Witam

Czy w PHP jest możliwy dostęp w klasie do prywatnego pola będącego tablicą, za pomocą tzw. „metod magicznych” __get i __set? Pytam, ponieważ używam wymienionych metod do uzyskiwania dostępu do pól klasy, które są typami prostymi lub obiektami i to działa całkiem przyzwoicie (wiem, że są pewne spadki wydajności ale to w chwili obecnej nie jest dla mnie kluczowe). Chciałbym niektóre utworzone przez siebie klasy wyposażyć we właściwości tablicowe. Przez pojęcie właściwości rozumiem tu mechanizm znany z języków takich jak C# czy ObjectPascal, gdzie w klasie istnieje pole, do którego dostęp odbywa się poprzez prywatne metody dostępowe (akcesory). Pozwala to np.: sprawdzać poprawność przekazywanych wartości (dla metody „set”) czy zwracać określoną wartość dla właściwości, która może nie posiadać odpowiadającego jej prywatnego pola w klasie a zwracana wartość jest np. obliczana (dla metody „get”). Żeby dobrze wyłuszczyć nurtujący mnie problem, przytoczę fragment hipotetycznej klasy:

  1. <?php
  2.  
  3. class TMyComponent
  4. {
  5. private $_count;
  6. private $_name;
  7. private $_values;
  8.  
  9. public function __construct()
  10. {
  11. $this->_ count = 0;
  12. $this->_name = "";
  13. $this->_values = array();
  14. }
  15.  
  16. public function __get($name)
  17. {
  18. $method = "get" . ucfirst($name);
  19. if (method_exists($this, $method))
  20. {
  21. return $this->$method();
  22. }
  23. }
  24.  
  25. public function __set($name, $value)
  26. {
  27. $method = "set" . ucfirst($name);
  28. if (method_exists($this, $method))
  29. {
  30. $this->$method($value);
  31. }
  32. }
  33.  
  34. private function getCount()
  35. {
  36. return $this->_count;
  37. }
  38.  
  39. private function getName()
  40. {
  41. return $this->_name;
  42. }
  43.  
  44. private function setName($value)
  45. {
  46. $this->_name = value;
  47. }
  48.  
  49. public function getValues($index)
  50. {
  51. $item = NULL;
  52. if ($this->isIndexValid($index))
  53. {
  54. $item = $this->_items[$index];
  55. }
  56. return $item;
  57. }
  58.  
  59. public function setValues($index, $value)
  60. {
  61. if ($this->isIndexValid($index))
  62. {
  63. $this->replace($index, $value);
  64. }
  65.  
  66. protected function isIndexValid($index)
  67. {
  68. $result = is_int($index) && ($index < $this->_count) && ($index >= 0);
  69. }
  70.  
  71. }
  72.  
  73. ?>


Dostęp do dwóch pierwszych pól w utworzonym obiekcie wyżej podanej klasy jest dość wygodny, np.:

  1. $myObj = new TMyComponent();
  2.  
  3. ...
  4.  
  5. $n = $myObj->count;
  6. $myObj->name = "abcdef";


Niestety do pola $_values można dostać się tylko przy jawnym wywołaniu metod getValues i setValues, np.:

  1. $oldValue = $myObj->getValues(2); // odczyt z komórki prywatnego pola klasy, gdzie pole jest tablicą
  2.  
  3. $myObj->setValues(2, 64); // zapis do komórki prywatnego pola klasy, gdzie pole jest tablicą


Czy w PHP jest możliwe takie przebudowanie wyżej podanego ciągu instrukcji metod __get i __set aby można było dostać się do pola $_values w taki sposób:

  1. $oldValue = $myObj->values[2]; // odczyt z komórki prywatnego pola klasy, gdzie $values jest właściwością tablicową (a nie polem klasy!)
  2.  
  3. $myObj->values[2] = 64; // zapis do komórki prywatnego pola klasy, gdzie $values jest właściwością tablicową (a nie polem klasy!)


Wg mojej wiedzy dotyczącej PHP (z pewnością niekompletnej), tego nie da się zaimplementować. A to dlatego, ponieważ metoda magiczna __get pobiera tylko jeden argument, którym jest nazwa właściwości. Niestety nie da się przekazać indeksu komórki do tablicy. Podobnie ma się rzecz z metodą magiczną __set, która pobiera tylko dwa argumenty, którymi są nazwa właściwości i wartość podlegająca przypisaniu do prywatnego pola. Być może się mylę i da się ten problem rozwiązać (co byłoby miłym zaskoczeniem). Rzecz jednak w tym, że dość skrupulatnie przekopywałem dział Help serwisu php.net. Próbowałem także przeszukiwać różne fora i blogi dotyczące programowania w PHP. Niestety nie natknąłem się na rozwiązanie takiego problemu. Jedyne na co trafiłem to na propozycje rozszerzenia języka PHP o metody dostępowe get i set działające podobnie jak w C# (tu: https://bugs.php.net/bug.php?id=49526, ale ta propozycja została odrzucona a szkoda, bo ten mechanizm wydaje się być o wiele lepszy niż tzw. "metody magiczne").

Czy jest zatem możliwe obsłużenie w klasie prywatnego pola-tablicy za pomocą metod magicznych __get i __set?
Go to the top of the page
+Quote Post

Posty w temacie


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 Wersja Lo-Fi Aktualny czas: 20.05.2024 - 17:42