![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 3 Pomógł: 0 Dołączył: 26.07.2011 Ostrzeżenie: (0%) ![]() ![]() |
Witam
Zakupiłem książkę PHP i MySQL. Projekty do wykorzystania: http://helion.pl/ksiazki/php-i-mysql-proje...inas,phmspr.htm Znajduje się w niej kod odpowiadający za mechanizm rejestracji i logowania użytkowników, który w kolejnych rozdziałach jest bazą do tworzenia różnych przykładowych aplikacji. Jego zasadnicza częścią jest klasa User, której kod przedstawiam poniżej:
Zdeklarowana w klasie metoda dostępowa __SET: Kod public function __set($field, $value) { if (array_key_exists($field, $this->fields)) { $this->fields[$field] = $value; } } przewiduje jedynie zapis do pola fields, które za sprawą konstruktora rozbudowywane jest do rozmiarów tablicy. Jak zatem możliwy jest zapis do pola $uid występujący np. w metodzie public static function getById($uid)? Czy ktoś mógłby to wyjaśnić? Wiem, że mógłbym uniknąć całego problemu zmieniając pola z private na public lub deklarując w __SET obsługę także pola $uid ale mnie interesuje zrozumiane tego jak to się dzieje, że zapis do pola $uid jest w ogóle możliwy mimo braku obsługi tegoż pola w metodzie __SET. Za pomoc z góry dziękuję. Cały rozdział(1) w którym umieszczona została przytoczona powyżej klasa jest dostępny na stronie: http://pdf.helion.pl/phmspr/phmspr-1.pdf Dostępny jest także kod z tego rozdziału: ftp://ftp.helion.pl/przyklady/phmspr.zip |
|
|
![]() |
![]()
Post
#2
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
Pamiętaj, że zmienne choć prywatne, są widoczne dla metod tejże klasy. Co z tego, że $obiekt->uid = 5 wywali błąd, skoro masz metodę, która wewnątrz widzi $this->uid i może z nią robić co chce
![]() -------------------- Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
|
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 2 178 Pomógł: 596 Dołączył: 25.09.2009 Skąd: Piwniczna-Zdrój Ostrzeżenie: (0%) ![]() ![]() |
Z manuala PHP:
Cytat __set() is run when writing data to inaccessible properties. Oznacza to, że operator -> za pomocą domyślnej metody __set() w pierwszej kolejności próbuje uzyskać dostęp do zadeklarowanych właściwości (property) klasy o określonym zasięgu, a w przypadku, gdy danej właściwości nie ma lub nie ma do niej dostępu następuje przeciążenie wyżej wspomnianej metody __set(), które to realizuje Twoja funkcja. |
|
|
![]()
Post
#4
|
|
Grupa: Zarejestrowani Postów: 3 Pomógł: 0 Dołączył: 26.07.2011 Ostrzeżenie: (0%) ![]() ![]() |
Jest więc tak, że metody klasy mogą uzyskiwać dostęp i możliwość zapisu do dowolnego pola klasy (w tym pola prywatnego) o ile tego typu operacja rozgrywa się w ramach tejże klasy nie wychodząc poza jej obręb. Natomiast jeżeli spoza klasy chciałbym ustawić wartość pola $uid to taka operacja nie jest możliwa gdyż metoda dostępowa __set w tym wypadku nie obsługuje zmiany $uid z pozycji (zewnętrznego wobec klasy User) obiektu klasy User.
W kodzie o którym mowa metoda __set właściwe kieruje jedynie tym gdzie mają być zapisywane wartości tzn. wskazuje zapis do konkretnych pozycji tablicy fields, która jest jednocześnie polem. Bez "nawigacji" prowadzonej przez __set dane zapisywane byłyby wprost do pól klasy czyli do pól takich jak $uid i dlatego też $uid, który nie jest ujęty w "nawigacji" realizowanej za pośrednictwem __set jest zapisywalny. Czy teraz dobrze rozumuje? Cytat przeciążenie wyżej wspomnianej metody __set(), które to realizuje Twoja funkcja. Jeszcze nie wiem co to jest przeciążenie metody ![]() Ten post edytował Ziuk 27.07.2011, 14:05:08 |
|
|
![]()
Post
#5
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
Dobrze rozumiesz Ziuk. Wewnątrz klasy każda metoda ma dostęp do pól na zasadzie specyfikatora public, bo jak wspomniałem: "To co moje może swobodnie sie ze soba porozumiewać". Tutaj co byś nie robił, to i tak każdy ma dostęp do wszystkiego. Stąd wewnątrz metod odwołania $this->pole są jak najbardziej poprawne. Dopiero próba odwołania zewnetrznego $obiekt_klasy->pole, jeśli byłoby ono private lub protected, jest naruszeniem. Własnie dlatego są metody magiczne __set i __get, które zwyczajowo są tworzone jako:
co sprawia, że jeśli nie istnieje własność o nazwie $field to tworzona jest wtedy niejawnie i wartość mu nadawana jest ustawiana na $value. W Twoim wypadku jest ona przeciążona/nadpisana w taki sposób, że odbywało się to nie wprost do obiektu ale do własności fields i to tylko, jeśli dany index istnieje w tej tablicy, na co zapewne nie zwróciłeś uwagi. Tak więc zapis $obiekt->password = 'test' da radę zrobić, ale juz $obiekt->losowe_pole = 'próba' nie powiedzie się, bo w tablicy fields brak indeksu o nazwie losowe_pole. Przeciążenie to deklaracja wielu wersji tej samej metody, przy czym kompilator/parser z kontekstu wychwytuje o która z nich chodzi. W PHP nie jest to tak widoczne, ponieważ jawne przeciążenie tu ciężko zrobić i odbywa się z kontekstu obiektu. Jest to lepiej widoczne w językach ze stałym typowaniem, gdzie choćby metoda( int zmienna) i metoda( float zmienna ) są dla komplilatora dwiema zupełnie innymi, choć o tej samej nazwie. Musiałbym sprawdzić jak PHP reaguje na metoda( array $zmienna ) i metoda( object $zmienna ) oraz metoda( $zmienna ), ale z tego co kojarzę to powinien się zbuntować coś o redeklaracji funkcji krzycząc ![]() -------------------- Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
|
|
|
![]() ![]() |
![]() |
Aktualny czas: 20.08.2025 - 06:39 |