wywołać metodę statyczną wewnątrz klasy?

166

jak wywołać metodę statyczną z innej metody w tej samej klasie?

$this->staticMethod();

lub

$this::staticMethod();
ajsie
źródło
13
To może Cię zainteresować (w selfporównaniu z $this): stackoverflow.com/questions/151969/php-self-vs-this
Felix Kling
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.
malhal

Odpowiedzi:

321
self::staticMethod();

Więcej informacji na temat słowa kluczowego Static.

jeroen
źródło
...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::
blamb
44

Załóżmy, że to Twoja klasa:

class Test
{
    private $baz = 1;

    public function foo() { ... }

    public function bar() 
    {
        printf("baz = %d\n", $this->baz);
    }

    public static function staticMethod() { echo "static method\n"; }
}

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.

Aby zobaczyć to wszystko w akcji, zobacz to wyjście 3v4l.org .

Jacek
źródło
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.

Weźmy na przykład ten kod:

class static_test_class {
    public static function test() {
        echo "Original class\n";
    }

    public static function run($use_self) {
        if($use_self) {
            self::test();
        } else {
            $class = get_called_class();
            $class::test(); 
        }
    }
}

class extended_static_test_class extends static_test_class {
    public static function test() {
        echo "Extended class\n";
    }
}

extended_static_test_class::run(true);
extended_static_test_class::run(false);

Wynik tego kodu to:

Oryginalna klasa

Rozszerzona klasa

Dzieje się tak, ponieważ selfodwoł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:

$class = get_called_class();
$class::function_name(); 
Joundill
źródło
2
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

oto przykład

class Foo {

    public function fun1() {
        echo 'non-static';   
    }

    public static function fun2() {
        echo (new self)->fun1();
    }
}
Nishad Up
źródło
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.
ToolmakerSteve