Po prostu FYI, pierwszym przykładem jest zmienna instancji wywołująca metodę statyczną, co nie jest możliwe, ponieważ metoda statyczna jest częścią klasy i nie jest dostępna za pośrednictwem zmiennej instancji.
joejoeson
możesz teraz usunąć $ this, proszę, nie działa, jeśli używasz tylko metod statycznych i nie istnieje żadna instancja.
...ale dlaczego? $ this-> staticMethod () też działa. Czy możesz wyjaśnić, dlaczego self :: staticMethod () jest bardziej poprawne (jeśli tak)?
Ian Dunn
29
@Ian Dunn Mówiąc prościej, $thisistnieje tylko wtedy, gdy utworzono instancję obiektu i można go używać tylko $this->methodz poziomu istniejącego obiektu. Jeśli nie masz obiektu, ale po prostu wywołujesz metodę statyczną, aw tej metodzie chcesz wywołać inną metodę statyczną w tej samej klasie, musisz użyć self::. Dlatego, aby uniknąć potencjalnych błędów (i ścisłych ostrzeżeń), lepiej jest użyć self.
jeroen
1
Dzięki! W laravel odkryłem, że przypadkowo wywołałem metodę statyczną na rozszerzonym kontrolerze $this, ale problem nie pojawił się, dopóki kod nie został przekazany stage. nie wróciły żadne błędy, wartość była po prostu 0. uważaj na to, użyjself::
foo()Przyjrzyjmy się różnym opcjom w ramach metody:
$this->staticMethod();
Więc to wywołania staticMethod()jako metoda instancji, prawda? To nie. Dzieje się tak, ponieważ metoda jest zadeklarowana, ponieważ public staticinterpreter wywoła ją jako metodę statyczną, więc będzie działać zgodnie z oczekiwaniami. Można argumentować, że takie postępowanie sprawia, że na podstawie kodu mniej oczywistym jest, że ma miejsce wywołanie metody statycznej.
$this::staticMethod();
Od PHP 5.3 możesz używać $var::method()na myśli <class-of-$var>::; jest to całkiem wygodne, chociaż powyższy przypadek użycia jest nadal dość niekonwencjonalny. To prowadzi nas do najczęstszego sposobu wywoływania metody statycznej:
self::staticMethod();
Teraz, zanim zaczniesz myśleć, że ::jest operator call statyczne, podam inny przykład:
self::bar();
To się wydrukuje baz = 1, co oznacza, że $this->bar()i self::bar()zrobi dokładnie to samo; to dlatego, że ::jest tylko operatorem rozpoznawania zakresu. Jest tam zrobić parent::, self::a static::prace i daje dostęp do zmiennych statycznych; sposób wywołania metody zależy od jej podpisu i sposobu wywołania obiektu wywołującego.
self::bar()wydaje się mylące - czy to teraz jest przestarzałe? (przy użyciu self::do wywołania metody instancji zamiast metody statycznej).
ToolmakerSteve
@ToolmakerSteve, w jaki sposób można powiedzieć, że wprowadza w błąd?
Ja͢ck,
Mówiąc logicznie, nie ma takiej selfsytuacji podczas wywoływania metody statycznej. Z definicji: metoda statyczna jest wywoływana z dowolnego miejsca i nie otrzymuje parametru „self”. Niemniej jednak widzę wygodę tej phpskładni, dzięki czemu nie musisz pisać MyClassName::. Jestem przyzwyczajony do języków typowanych statycznie, gdzie kompilator musi mieć wszystkie dostępne w bieżącym zakresie zmienne, więc self::można pominąć (odpowiednik) . Tak więc tylko jeden powiedział self instanceMethod; nie ma powodu by mówić self staticMethod.
ToolmakerSteve
15
To bardzo późna odpowiedź, ale dodaje trochę szczegółów do poprzednich odpowiedzi
Jeśli chodzi o wywoływanie metod statycznych w PHP z innej metody statycznej tej samej klasy, ważne jest, aby odróżnić selfnazwę klasy od jej nazwy.
Znalazłem to pouczające. Mała głupota, nie powiedziałbym, że inne odpowiedzi są „mylące”. Bardziej trafne jest stwierdzenie, że są one „niekompletne”; nie odnoszą się do (nie zadanego) pytania, co self::robi w (rzadkim) przypadku, gdy metoda statyczna A wywołuje inną metodę statyczną B, a B została zastąpiona w podklasie. IMHO, mniej kłopotliwe jest ograniczenie nadpisywania metody do metod „instancji”; używaj tej zdolności oszczędnie na poziomie statycznym. Ujmując to inaczej, czytelnicy Twojego kodu oczekują przesłaniania metod instancji (to jest istota kodowania obiektowego), ale nie statycznych.
ToolmakerSteve
1
Bardzo pomocny i ma sens, że rozszerzenie klasy nie jest klasą oryginalną. Dlatego rozsądne jest, selfże nie zostałoby to użyte w tym przypadku. Zadeklarowałeś oddzielną klasę jako rozszerzenie pierwszej klasy. Używanie selfw klasie rozszerzonej odnosiłoby się do klasy rozszerzonej. Nie jest to sprzeczne z innymi odpowiedziami, ale z pewnością pomaga wykazać zakres self.
iyrin
2
W późniejszej wersji PHP self::staticMethod();również nie będzie działać. Spowoduje to wyświetlenie ścisłego błędu standardowego.
W takim przypadku możemy stworzyć obiekt tej samej klasy i wywołać po obiekcie
Możesz to zrobić, ale jeśli fun1nie używasz self, nie jest logiczne, aby uczynić z niej metodę instancji. Właściwym sposobem, aby to zrobić w PHP jest zadeklarować public static function fun1, a następnie zadzwonić, określając klasę: Foo::fun1. Jestem pewien, że to zamierzony sposób naprawienia tego surowego błędu standardowego.
self
porównaniu z$this
): stackoverflow.com/questions/151969/php-self-vs-thisOdpowiedzi:
Więcej informacji na temat słowa kluczowego Static.
źródło
$this
istnieje tylko wtedy, gdy utworzono instancję obiektu i można go używać tylko$this->method
z poziomu istniejącego obiektu. Jeśli nie masz obiektu, ale po prostu wywołujesz metodę statyczną, aw tej metodzie chcesz wywołać inną metodę statyczną w tej samej klasie, musisz użyćself::
. Dlatego, aby uniknąć potencjalnych błędów (i ścisłych ostrzeżeń), lepiej jest użyćself
.$this
, ale problem nie pojawił się, dopóki kod nie został przekazanystage
. nie wróciły żadne błędy, wartość była po prostu0
. uważaj na to, użyjself::
Załóżmy, że to Twoja klasa:
foo()
Przyjrzyjmy się różnym opcjom w ramach metody:Więc to wywołania
staticMethod()
jako metoda instancji, prawda? To nie. Dzieje się tak, ponieważ metoda jest zadeklarowana, ponieważpublic static
interpreter wywoła ją jako metodę statyczną, więc będzie działać zgodnie z oczekiwaniami. Można argumentować, że takie postępowanie sprawia, że na podstawie kodu mniej oczywistym jest, że ma miejsce wywołanie metody statycznej.Od PHP 5.3 możesz używać
$var::method()
na myśli<class-of-$var>::
; jest to całkiem wygodne, chociaż powyższy przypadek użycia jest nadal dość niekonwencjonalny. To prowadzi nas do najczęstszego sposobu wywoływania metody statycznej:Teraz, zanim zaczniesz myśleć, że
::
jest operator call statyczne, podam inny przykład:To się wydrukuje
baz = 1
, co oznacza, że$this->bar()
iself::bar()
zrobi dokładnie to samo; to dlatego, że::
jest tylko operatorem rozpoznawania zakresu. Jest tam zrobićparent::
,self::
astatic::
prace i daje dostęp do zmiennych statycznych; sposób wywołania metody zależy od jej podpisu i sposobu wywołania obiektu wywołującego.Aby zobaczyć to wszystko w akcji, zobacz to wyjście 3v4l.org .
źródło
self::bar()
wydaje się mylące - czy to teraz jest przestarzałe? (przy użyciuself::
do wywołania metody instancji zamiast metody statycznej).self
sytuacji podczas wywoływania metody statycznej. Z definicji: metoda statyczna jest wywoływana z dowolnego miejsca i nie otrzymuje parametru „self”. Niemniej jednak widzę wygodę tejphp
składni, dzięki czemu nie musisz pisaćMyClassName::
. Jestem przyzwyczajony do języków typowanych statycznie, gdzie kompilator musi mieć wszystkie dostępne w bieżącym zakresie zmienne, więcself::
można pominąć (odpowiednik) . Tak więc tylko jeden powiedziałself instanceMethod
; nie ma powodu by mówićself staticMethod
.To bardzo późna odpowiedź, ale dodaje trochę szczegółów do poprzednich odpowiedzi
Jeśli chodzi o wywoływanie metod statycznych w PHP z innej metody statycznej tej samej klasy, ważne jest, aby odróżnić
self
nazwę klasy od jej nazwy.Weźmy na przykład ten kod:
Wynik tego kodu to:
Dzieje się tak, ponieważ
self
odwołuje się do klasy, w której znajduje się kod, a nie do klasy kodu, z którego jest wywoływany.Jeśli chcesz użyć metody zdefiniowanej w klasie, która dziedziczy oryginalną klasę, musisz użyć czegoś takiego:
źródło
self::
robi w (rzadkim) przypadku, gdy metoda statyczna A wywołuje inną metodę statyczną B, a B została zastąpiona w podklasie. IMHO, mniej kłopotliwe jest ograniczenie nadpisywania metody do metod „instancji”; używaj tej zdolności oszczędnie na poziomie statycznym. Ujmując to inaczej, czytelnicy Twojego kodu oczekują przesłaniania metod instancji (to jest istota kodowania obiektowego), ale nie statycznych.self
że nie zostałoby to użyte w tym przypadku. Zadeklarowałeś oddzielną klasę jako rozszerzenie pierwszej klasy. Używanieself
w klasie rozszerzonej odnosiłoby się do klasy rozszerzonej. Nie jest to sprzeczne z innymi odpowiedziami, ale z pewnością pomaga wykazać zakresself
.W późniejszej wersji PHP
self::staticMethod();
również nie będzie działać. Spowoduje to wyświetlenie ścisłego błędu standardowego.W takim przypadku możemy stworzyć obiekt tej samej klasy i wywołać po obiekcie
oto przykład
źródło
fun1
nie używaszself
, nie jest logiczne, aby uczynić z niej metodę instancji. Właściwym sposobem, aby to zrobić w PHP jest zadeklarowaćpublic static function fun1
, a następnie zadzwonić, określając klasę:Foo::fun1
. Jestem pewien, że to zamierzony sposób naprawienia tego surowego błędu standardowego.