Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Określanie poziomu uruchomienia metody
Forum PHP.pl > Forum > PHP > Pro > Archiwum Pro
luinnar
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?
Nievinny
Wszystko zależy od ilości odwołań:
do 10 nie masz się czym przejmować,
przy 1000 jeszcze znośnie,
ale przy 10 tyś. to już jest sporo.

Moim zdaniem jeżeli skrypt uruchamia 100 użytkowników w jednym momencie a odwołań jest powiedzmy 1000 to wtedy:
x - czas generowania bez kontroli
100x - to samo tylko dla 100 userów
x + 0.025 - czas gen. z kontrolą
100x + 2.5 - to samo dla 100 userów

Nie zostało tu uwzględnione obciążenie serwera (uznałem to za stałą z powodu, że trochę się śpieszę). Serwer będzie miał więcej do zrobienia, ale przy takiej ilości wywołań nie powinien się buntować. Nie możemy przecież panicznie bać się każdej dodatkowej milisekundy. Optymalizacja - tak, ale w granicach rozsądku (wkład nie może być większy niż dobro które powstaje). Bardziej zagłębię się w temat jak trochę mnie zluzują...
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-2024 Invision Power Services, Inc.