Buduję klasy użytkownika dla mojej nowej strony internetowej, jednak tym razem myślałem o zbudowaniu jej trochę inaczej ...
C ++ , Java, a nawet Ruby (i prawdopodobnie inne języki programowania) pozwalają na użycie zagnieżdżonych / wewnętrznych klas wewnątrz głównej klasy, co pozwala nam uczynić kod bardziej zorientowanym obiektowo i zorganizowanym.
W PHP chciałbym zrobić coś takiego:
<?php
public class User {
public $userid;
public $username;
private $password;
public class UserProfile {
// some code here
}
private class UserHistory {
// some code here
}
}
?>
Czy to możliwe w PHP? Jak mogę to osiągnąć?
AKTUALIZACJA
Jeśli to niemożliwe, czy przyszłe wersje PHP będą obsługiwać klasy zagnieżdżone?
User
, na przykład:public class UserProfile extends User
ipublic class UserHestory extends User
.Odpowiedzi:
Wstęp:
Klasy zagnieżdżone odnoszą się do innych klas nieco inaczej niż klasy zewnętrzne. Biorąc Javę jako przykład:
Zagnieżdżone klasy niestatyczne mają dostęp do innych członków otaczającej klasy, nawet jeśli zostały zadeklarowane jako prywatne. Ponadto niestatyczne klasy zagnieżdżone wymagają utworzenia instancji klasy nadrzędnej.
Istnieje kilka istotnych powodów, dla których warto ich używać:
W PHP
Możesz mieć podobne zachowanie w PHP bez zagnieżdżonych klas.
Jeśli wszystko, co chcesz osiągnąć, to struktura / organizacja, jak Package.OuterClass.InnerClass, przestrzenie nazw PHP mogą wystarczyć. Możesz nawet zadeklarować więcej niż jedną przestrzeń nazw w tym samym pliku (chociaż ze względu na standardowe funkcje automatycznego ładowania, może to nie być zalecane).
Jeśli chcesz naśladować inne cechy, takie jak widoczność członków, wymaga to trochę więcej wysiłku.
Definiowanie klasy „pakietu”
Przypadek użycia
Testowanie
Wynik:
UWAGA:
Naprawdę nie sądzę, aby próba emulacji innerClasses w PHP była tak dobrym pomysłem. Myślę, że kod jest mniej czysty i czytelny. Prawdopodobnie istnieją również inne sposoby osiągnięcia podobnych wyników przy użyciu dobrze ugruntowanego wzorca, takiego jak Wzorzec obserwatora, dekoratora lub układu współrzędnych. Czasami nawet proste dziedziczenie jest wystarczające.
źródło
Prawdziwe zagnieżdżone klasy z
public
/protected
/private
accessibility zostały zaproponowane w 2013 roku dla PHP 5.6 jako RFC, ale tego nie zrobiły (brak głosowania, brak aktualizacji od 2013 - od 2016/12/29 ):https://wiki.php.net/rfc/nested_classes
Przynajmniej klasy anonimowe trafiły do PHP 7
https://wiki.php.net/rfc/anonymous_classes
Z tej strony RFC:
Więc możemy otrzymać zagnieżdżone klasy w jakiejś przyszłej wersji, ale nie jest to jeszcze zdecydowane.
źródło
Nie możesz tego zrobić w PHP. Jednak są funkcjonalne sposoby, aby to osiągnąć.
Aby uzyskać więcej informacji, sprawdź ten post: Jak zrobić zagnieżdżoną klasę PHP lub zagnieżdżone metody?
Ten sposób implementacji nazywa się płynnym interfejsem: http://en.wikipedia.org/wiki/Fluent_interface
źródło
Od wersji PHP 5.4 możesz wymusić tworzenie obiektów z prywatnym konstruktorem poprzez odbicie. Może służyć do symulacji zagnieżdżonych klas Java. Przykładowy kod:
źródło
Zgodnie z komentarzem Xenona do odpowiedzi Anıl Özselgin, klasy anonimowe zostały zaimplementowane w PHP 7.0, który jest tak bliski klasom zagnieżdżonym, jak teraz. Oto odpowiednie specyfikacje RFC:
Klasy zagnieżdżone (stan: wycofane)
Klasy anonimowe (stan: zaimplementowane w PHP 7.0)
Przykład oryginalnego posta, tak wyglądałby Twój kod:
To jednak wiąże się z bardzo nieprzyjemnym zastrzeżeniem. Jeśli używasz IDE, takiego jak PHPStorm lub NetBeans, a następnie dodaj do
User
klasy metodę podobną do tej :... pa pa autouzupełnianie. Dzieje się tak, nawet jeśli kodujesz do interfejsów (I w SOLID), używając wzoru takiego:
O ile twoje jedyne wywołania do
$this->profile
nie pochodzą z__construct()
metody (lub jakiejkolwiek metody$this->profile
zdefiniowanej w), nie otrzymasz żadnych podpowiedzi typu. Twoja własność jest zasadniczo „ukryta” w Twoim IDE, co bardzo utrudnia życie, jeśli polegasz na swoim IDE w zakresie autouzupełniania, wykrywania zapachu kodu i refaktoryzacji.źródło
Nie możesz tego zrobić w PHP. PHP obsługuje "dołączanie", ale nie możesz tego zrobić nawet wewnątrz definicji klasy. Nie ma tu wielu świetnych opcji.
To nie odpowiada bezpośrednio na twoje pytanie, ale możesz być zainteresowany "Przestrzeniami nazw", strasznie brzydkim \ syntax \ hacked \ on \ top \ PHP OOP: http://www.php.net/manual/en/language .namespaces.rationale.php
źródło
Czeka na głosowanie jako RFC https://wiki.php.net/rfc/anonymous_classes
źródło
Myślę, że napisałem eleganckie rozwiązanie tego problemu przy użyciu przestrzeni nazw. W moim przypadku klasa wewnętrzna nie musi znać swojej klasy nadrzędnej (podobnie jak statyczna klasa wewnętrzna w Javie). Jako przykład stworzyłem klasę o nazwie „Użytkownik” i podklasę o nazwie „Typ”, używaną jako odniesienie dla typów użytkowników (ADMINISTRATOR, INNE) w moim przykładzie. Pozdrowienia.
User.php (plik klasy użytkownika)
Using.php (przykład wywołania „podklasy”)
źródło
Możesz w ten sposób w PHP 7:
źródło
Umieść każdą klasę w osobnych plikach i „wymagaj” ich.
User.php
UserProfile.php
UserHistory.php
źródło