Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Określanie poziomu uruchomienia metody, a wydajność
luinnar
post
Post #1





Grupa: Zarejestrowani
Postów: 155
Pomógł: 0
Dołączył: 15.07.2004
Skąd: Bielsko-Biała

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


Witam!

Mam nadzieję, że temat który poruszę pasuje do tego miejsca.

Pierwsze opiszę dziedzinę zagadnienia:

Posiadam klasę, która zajmuje się przechowywaniem dowolnych danych (jej dokładna implementacja nie jest dziedziną problemu), ma dość dużą funkcjonalność (iterowanie, zachowywanie zbieżności z danymi zapisywanymi na stałe itp.). Dla naszych rozważań będę nazywał ją test. Klasa test ma 2 interesujące nas metody: get($sName) i set($sName, $mVal) służą one oczywiście do pobierania i zapisywania umieszczonych wewnątrz danych.

Szkic implementacji:
  1. <?php
  2. class test
  3. {
  4. private $aTable = array('a' => 'a', 'b' => 'b', 'c' => 'c');
  5.  
  6. public function get($mName)
  7. {
  8. return $this->aTable[$mName];
  9. }
  10.  
  11. public function set($sName, $mVal)
  12. {
  13. $this->aTable[$sName] = $mVal;
  14. }
  15. }
  16. ?>

Jak wszyscy wiemy same dane to dopiero 30% sukcesu, trzeba na nich jakoś operować. Dlatego najczęściej piszemy klasę, która zawiera dane i metody operujące na nich. Szkoda jednak aby tak duża funkcjonalność klasy się zmarnowała, może ona przechowywać dla nas dowolne dane, zapisywać je w odpowiednie miejsce bez naszego kiwnięcia palcem! Daltego najlepiej byłoby w jakiś sposób rozszerzyć jej funkcjonalność. Nazwijmy nową klasę (operującą na danych z klasy test) test2:
  1. <?php
  2. class test2
  3. {
  4. public function __construct($Obj)
  5. {
  6. $this->Test = $Obj;
  7. }
  8.  
  9. public function getA()
  10. {
  11. return $this->Test->get('a');
  12. }
  13. }
  14. ?>

Operowanie w taki sposób na danych w klasie jest niewygodne, dlatego kolejnym krokiem mogłoby być dziedziczenie (musimy także pamiętać aby dane miały zasięg niepubliczny dlatego w klasie test akcesor public zamieniamy na protected):
  1. <?php
  2. class test2 extends test
  3. {
  4. public function getA()
  5. {
  6. return $this->get('a');
  7. }
  8. }
  9. ?>

Jednak w dalszym ciągu projektowanie takiego rozwinięcia do klasy test jest utrudnione. Najlepszym efektem byłoby bezpośrednie używanie zmiennych:
Kod
$this->a
Wydaje się teraz oczywiste użycie magicznych funkcji __get i __set:
  1. <?php
  2. class test
  3. {
  4. private $aTable = array('a' => 'a', 'b' => 'b', 'c' => 'c');
  5.  
  6. protected function __get($mName)
  7. {
  8. return $this->aTable[$mName];
  9. }
  10.  
  11. protected function __set($sName, $mVal)
  12. {
  13. $this->aTable[$sName] = $mVal;
  14. }
  15. }
  16. ?>
Niby wszystko działa... Jednak stała się katastrofa, metody __set i __get zawsze są publiczne. Dlatego możemy zrobić tak:
  1. <?php
  2. $Obj = new test2();
  3. $Obj->a = 5;
  4. ?>
Co może prowadzić do katastrofy.

Problem ten teoretycznie można rozwiązań używając funkcji debug_backtrace(). Oto teoretyczne rozwiązanie: http://phpfi.com/169155 . Takie rozwiązanie ma pewne plusy: możemy ustalać zasięg zmiennych, jednak z moich pomiarów wynika, że każde takie odwołanie jest o około 0.000025 sec wolniejsze niż bez sprawdzania miejsca uruchomienia.

Teraz podstawowe pytania: Czy taki czas jest dopuszczalny dla takiego ułatwienia? Może ktoś widzi inny sposób rozwiązania takiego przypadku?
Go to the top of the page
+Quote Post

Posty w temacie


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

 



RSS Aktualny czas: 27.09.2025 - 15:25