Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: metody __set i __get
Forum PHP.pl > Forum > PHP
ramedlaw
Witam

Czytam sobie książkę "PHP i MySQL. Tworzenie stron WWW. Vademecum profesjonalisty".
Podano tam taki przykład (mniej więcej):

class A
{
public $atr;

public __set($name, $value)
{
....
}

public __get($name)
{
...
}

}

$obj = new A();
$obj->atr = cos;
echo $obj->atr;

Z moich testów wynika, że metody dostępowe wyzwalają się gdy atrybut jest private/protected a nie public.
Pytam więc czy w książce jest błąd? Czy może w PHP 5.0 tak było i zostało zmienione? A może ja coś pokręciłem?
drPayton
Jeśli zmienna jest publiczna, nie będą wywoływane metody magiczne __set i __get. Jest to wyraźnei napisane w manualu. Nie przypominam sobie, żeby kiedyś było inaczej, ale kto wie...

edit: Usunąłem swoje wypociny pozostawiając odpowiedź na Twoje pytanie tylko winksmiley.jpg
thek
Różnica między private i public wynika z podejścia dostępu do zawartości klasy.
Zmienne i funkcje publiczne klasy są dostępne zawsze dla wszystkich z zewnątrz i możesz się do nich dobrać poprzez proste odwołanie do obiektu jak choćby obiekt.zmienna bo jest na to zezwolenie. Jeśli coś jest zadeklarowane jako prywatne, możesz się do tego dobrać tylko i wyłącznie odpowiednimi funkcjami tej klasy. Ty dałeś __set i __get jako publiczne bez sprawdzania jaką zmienną wywołano by. Tym samym udostępniłeś możliwość odczytu i zapisu wszystkich zmiennych klasy, w tym prywatnych (!). Musisz zrobić dodatkowy warunek, który w razie odwołania do zmiennej nie istniejącej poinformuje o braku takowej lub wyświetli info o braku dostępu dla prywatnych danych. W tym momencie wszyscy mają dostęp do jakich chcą, nawet do tych, których nie chciałeś upubliczniać. Można to potraktować jako lukę bezpieczeństwa. Właśnie do tego zostały te funkcje w dużej mierze wymyślone... By reagować na wywołania czegoś co nie istnieje i są niejako idealne do wykorzystywania przy obsłudze wyjątków smile.gif
drPayton
Cytat(thek @ 26.08.2009, 11:35:46 ) *
(...)Można to potraktować jako lukę bezpieczeństwa. Właśnie do tego zostały te funkcje w dużej mierze wymyślone... By reagować na wywołania czegoś co nie istnieje i są niejako idealne do wykorzystywania przy obsłudze wyjątków smile.gif


Jest to jeden z przykładów użycia, ale chociażby Rejestr realizuje się poprzez wykorzystanie tych metod właśnie w celu prostego dostępu do zmiennych oraz tworzenia nieistniejących kluczy tablic (np) winksmiley.jpg

To, czy jest to luka bezpieczeństwa czy nie, zależy od tego co chcemy tym osiągnąć.

Ale to na marginesie, bo @ramedlaw pytał o coś innego winksmiley.jpg
ramedlaw
Dzięki za odpowiedzi, wychodzi na to, że w książce jest mały błąd. Jeśli chodzi o lukę w bezpieczeństwie to oczywiście podałem tylko przykład. W metodach (szczególnie w __set) należy powstawiać różne warunki.
Fifi209
Żadna luka w bezpieczeństwie...

  1.  
  2. class test {
  3.  
  4. private $vars;
  5. private $other='aaa';
  6.  
  7. public function __set($key, $value) {
  8. $this->vars[$key] = $value;
  9. }
  10.  
  11. }

Jak mądrale dostaniecie się do $test->other ?

Jak się programuje to trzeba myśleć.
zzeus
W ten sposób jak Ty napisałeś nie da się, ale ograniczasz poprzez tą metodę dostęp do jednej zmiennej w klasie. Metody magiczne mają chyba dawać dostęp do wszystkich zmiennych klasy, twój zapis jest równoważny zapisowi
  1. public function setVars($key, $value)
  2. {
  3. $this->vars[$key] = $value;
  4. }

a to chyba nie o to chodzi w metodach magicznych.
drPayton
@zzeus: Ale właśnie o to chodzi, żeby wszystkie zmienne ustawiane "magicznie" trafiały do takiej tablicy. Wtedy masz nad tym pełną kontrolę.

Aż jeszcze raz napiszę: Zależy do czego chcemy te metody wykorzystać:
1. Do obsługi błędów (nieprawidłowa nazwa zmiennej np) jak pisał @thek
2. Elegancki rejestr (wtedy najczęściej tablica)
3. No nie jestem w stanie wyobrazić sobie sytuacji, kiedy chcielibyśmy odbierać i podawać "pojedyncze" (w sensie nie klucz w tablicy) zmienne prywatne klasy ^^ Ale może jednak?
Fifi209
Cytat(zzeus @ 26.08.2009, 12:24:04 ) *
W ten sposób jak Ty napisałeś nie da się, ale ograniczasz poprzez tą metodę dostęp do jednej zmiennej w klasie. Metody magiczne mają chyba dawać dostęp do wszystkich zmiennych klasy, twój zapis jest równoważny zapisowi
  1. public function setVars($key, $value)
  2. {
  3. $this->vars[$key] = $value;
  4. }

a to chyba nie o to chodzi w metodach magicznych.


Mają dawać dostęp tylko do tych zmiennych o jakich myślał programista w czasie pisania aplikacji.

I nie jest równoznaczne. winksmiley.jpg __set jest wygodniejsze
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-2025 Invision Power Services, Inc.