Pytanie Kiedy użyć self over $ this?


W PHP 5, jaka jest różnica między używaniem self i $this?

Kiedy każdy jest odpowiedni?


1777
2017-09-30 06:23


pochodzenie


możliwy duplikat Nowa jaźń kontra nowa statyczność - Orangepill
Zamierzam zapytać, jaka jest różnica między: cont A; $ this-> A i self :: A - mboullouz


Odpowiedzi:


Krótka odpowiedź

Posługiwać się $this odnosić się do prądu   obiekt. Posługiwać się self odnosić się do   obecna klasa. Innymi słowy, użyj    $this->member dla członków niestatycznych,   posługiwać się self::$member dla członków statycznych.

Pełna odpowiedź

Oto przykład poprawny użycie $this i self dla niestałych i statycznych zmiennych składowych:

<?php
class X {
    private $non_static_member = 1;
    private static $static_member = 2;

    function __construct() {
        echo $this->non_static_member . ' '
           . self::$static_member;
    }
}

new X();
?>

Oto przykład błędny użycie $this i self dla niestałych i statycznych zmiennych składowych:

<?php
class X {
    private $non_static_member = 1;
    private static $static_member = 2;

    function __construct() {
        echo self::$non_static_member . ' '
           . $this->static_member;
    }
}

new X();
?>

Oto przykład wielopostaciowość z $this dla funkcji członka:

<?php
class X {
    function foo() {
        echo 'X::foo()';
    }

    function bar() {
        $this->foo();
    }
}

class Y extends X {
    function foo() {
        echo 'Y::foo()';
    }
}

$x = new Y();
$x->bar();
?>

Oto przykład tłumienie zachowania polimorficznego używając self dla funkcji członka:

<?php
class X {
    function foo() {
        echo 'X::foo()';
    }

    function bar() {
        self::foo();
    }
}

class Y extends X {
    function foo() {
        echo 'Y::foo()';
    }
}

$x = new Y();
$x->bar();
?>

Chodzi o to, że $this->foo() nazywa się foo() funkcja member jakiejkolwiek> jest dokładnym typem bieżącego obiektu. Jeśli obiekt jest type X, to w ten sposób> wywołuje X::foo(). Jeśli obiekt jest type Y, dzwoni Y::foo(). Ale z> self :: foo (), X::foo() jest zawsze wywoływana.

Od http://www.phpbuilder.com/board/showthread.php?t=10354489:

Przez http://board.phpbuilder.com/member.php?145249-laserlight


1512
2017-09-30 06:29



Ta odpowiedź jest zbyt uproszczona. Jak wskazano w innych odpowiedziach, self jest używany z operatorem rozdzielczości zakresu :: odnosić się do obecnej klasy; można to zrobić zarówno w kontekście statycznym, jak i nie statycznym. Dodatkowo jest to całkowicie legalne w użyciu $this wywoływać metody statyczne (ale nie odwoływać się do pól). - Artefacto
Rozważ także użycie static :: zamiast :: self, jeśli jesteś w wersji 5.3+. Może to spowodować niezliczone bóle głowy w inny sposób, zobacz moją odpowiedź poniżej, dlaczego. - Sqoo
-1. Ta odpowiedź jest myląca, przeczytaj inne odpowiedzi, aby uzyskać więcej informacji. - Pacerier
Może to być nadmiernie uproszczone, ale odpowiedział na moje podstawowe pytanie bez rozbijania sobie głowy. Dostałem więcej informacji, które uważałem za pomocne w dalszej części, ale na razie próbowałem po prostu dowiedzieć się, dlaczego uderzyłem w atrybuty klasy za pomocą $ this-> attrib i stałe klasy self = constant. Pomogło mi to lepiej to zrozumieć - MydKnight
Co powiesz na $this::? - James


Słowo kluczowe samo robi NIE odnoszą się jedynie do "obecnej klasy", przynajmniej nie w taki sposób, który ogranicza was do statycznych członków. W kontekście niestatycznego członka, self zapewnia również sposób ominięcia tabeli vtable (zobacz wiki na vtable) dla bieżącego obiektu. Tak jak możesz użyć parent::methodName() aby zadzwonić do macierzystej wersji funkcji, dzięki czemu możesz zadzwonić self::methodName() wywołanie aktualnej klasy implementacji metody.

class Person {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }

    public function getTitle() {
        return $this->getName()." the person";
    }

    public function sayHello() {
        echo "Hello, I'm ".$this->getTitle()."<br/>";
    }

    public function sayGoodbye() {
        echo "Goodbye from ".self::getTitle()."<br/>";
    }
}

class Geek extends Person {
    public function __construct($name) {
        parent::__construct($name);
    }

    public function getTitle() {
        return $this->getName()." the geek";
    }
}

$geekObj = new Geek("Ludwig");
$geekObj->sayHello();
$geekObj->sayGoodbye();

To wyświetli:

Cześć, jestem Ludwigem maniakiem
     Żegnaj od Ludwiga

sayHello() używa $this wskaźnik, więc vtable jest wywoływany, aby wywołać Geek::getTitle(). sayGoodbye() używa self::getTitle(), więc vtable nie jest używany, i Person::getTitle() jest nazywany. W obu przypadkach mamy do czynienia z metodą instancji obiektu i mamy dostęp do $this wskaźnik w wywołanych funkcjach.


710
2017-07-27 18:00



Ta odpowiedź byłaby jeszcze lepsza, gdybyś zaczął od ogólnej reguły, a nie od wyjątku. To kwestia stylu, a nie technicznej wiedzy. To najlepszy przykład, jaki kiedykolwiek widziałem na różnicę między self :: i $ this->, ale szkoda to ukryć, najpierw obalając pojęcie. - adjwilli
@adjwilli: Dlaczego ten zły styl? Czy nie podnosi świadomości, jeśli oczekiwanie (teza) z OP jest najpierw odrzucone (antyteza), a następnie wyjaśnienie jest podane jako synteza? - hakre
Uważam, że "obecna klasa" jest naprawdę problematyczna. Ponieważ tę kombinację słów można rozumieć jako "klasę, w której self znajduje się "/" definicja klasy to dosłowna część "jak również" klasa obiektu "(która faktycznie byłaby static). - Jakumi
Co powiesz na $this::? - James


NIE UŻYWAJ self::, posługiwać się static::

Jest jeszcze jeden aspekt self ::, o którym warto wspomnieć. Denerwująco self:: odnosi się do zakresu w punkcie definicji, nie w miejscu wykonania. Rozważ tę prostą klasę dwiema metodami:

class Person
{

    public static function status()
    {
        self::getStatus();
    }

    protected static function getStatus()
    {
        echo "Person is alive";
    }

}

Jeśli zadzwonimy Person::status() zobaczymy "Osoba żyje". Teraz zastanów się, co się stanie, gdy utworzymy klasę, która dziedziczy z tego:

class Deceased extends Person
{

    protected static function getStatus()
    {
        echo "Person is deceased";
    }

}

Powołanie Deceased::status() spodziewalibyśmy się zobaczyć "Osoba nie żyje", ale widzimy, że "Osoba żyje", ponieważ zakres zawiera oryginalną definicję metody, gdy self::getStatus() został zdefiniowany.

PHP 5.3 ma rozwiązanie. static:: operator rozdzielczości implementuje "późne wiązanie statyczne", co jest fantazyjnym sposobem powiedzenia, że ​​jest ono związane z zakresem klasy nazywanej. Zmień linię w status() do static::getStatus() a wyniki są tym, czego można się spodziewać. W starszych wersjach PHP będziesz musiał znaleźć kludge, aby to zrobić.

Widzieć Dokumentacja PHP

Aby odpowiedzieć na pytanie, nie pytając ...

$this-> odnosi się do bieżącego obiektu (instancji klasy), podczas gdy static::odnosi się do klasy


429
2017-07-24 15:08



A co ze stałymi klasowymi? - Kevin Bond
Chyba to samo - Sqoo
"Calling Deceased :: status () spodziewamy się zobaczyć" Osoba nie żyje "". Nie. Jest to statyczne wywołanie funkcji, więc nie ma w nim polimorfizmu. - cquezel
@jasondavis dzięki, starałem się używać angielskiego i unikać takich terminów jak polimorfizm. Ta odpowiedź jest zwykle sformułowana w kategoriach, które rozumiałby tylko informatyk, PHP nie jest językiem skierowanym do informatyków! - Sqoo
Przykład wydaje mi się mylący: Rozumiem getStatus metodę jako taką, którą wywołuję dla instancji klasy, a nie dla klasy. - Jānis Elmeris


Aby naprawdę zrozumieć, o czym mówimy, kiedy mówimy self przeciw $thismusimy właściwie zagłębić się w to, co się dzieje na poziomie koncepcyjnym i praktycznym. Naprawdę nie czuję żadnej z odpowiedzi, które to robię właściwie, więc oto moja próba.

Zacznijmy od rozmowy o tym, co klasa i obiekt jest.

Klasy i przedmioty, koncepcyjnie

Więc co jest za klasa? Wiele osób definiuje to jako plan lub szablon dla obiektu. W rzeczywistości możesz przeczytać więcej O klasach w PHP tutaj. I do pewnego stopnia tak właśnie jest. Spójrzmy na klasę:

class Person {
    public $name = 'my name';
    public function sayHello() {
        echo "Hello";
    }
}

Jak można się domyślić, istnieje właściwość tej klasy o nazwie $name i wywołana metoda (funkcja) sayHello().

Jego bardzo ważne jest, aby pamiętać, że klasa jest statyczną strukturą. Co oznacza, że ​​klasa Person, po zdefiniowaniu, jest zawsze taki sam wszędzie, na co patrzysz.

Z drugiej strony obiekt to tzw instancja klasy. Oznacza to, że bierzemy "plan" klasy i używamy go do tworzenia dynamicznej kopii. Ta kopia jest teraz ściśle powiązana ze zmienną, w której jest przechowywana. Dlatego wszelkie zmiany w instancja jest lokalne dla tej instancji.

$bob = new Person;
$adam = new Person;
$bob->name = 'Bob';
echo $adam->name; // "my name"

Tworzymy nowe instancje klasy korzystającej z new operator.

Dlatego mówimy, że klasa jest strukturą globalną, a obiekt jest strukturą lokalną. Nie przejmuj się tym zabawnie -> składnia, zamierzamy w tym trochę pójść.

Jeszcze jedną rzeczą, o której powinniśmy porozmawiać, jest to, że możemy czek jeśli instancja jest instanceof konkretna klasa: $bob instanceof Person która zwraca wartość logiczną, jeśli $bob instancja została wykonana przy użyciu Person klasa, lub dziecko Person.

Definiowanie państwa

Tak więc, zagłębimy się nieco w to, co klasa faktycznie zawiera. Istnieje 5 typów "rzeczy", które klasa zawiera:

  1. Nieruchomości - Wyobraź sobie, że są to zmienne, które zawiera każda instancja.

    class Foo {
        public $bar = 1;
    }
    
  2. Właściwości statyczne - Pomyśl o nich jako o zmiennych, które są udostępniane na poziomie klasy. Oznacza to, że nie są one nigdy kopiowane przez każdą instancję.

    class Foo {
        public static $bar = 1;
    }
    
  3. Metody - Są to funkcje, które każda instancja zawiera (i działa na instancjach).

    class Foo {
        public function bar() {}
    }
    
  4. Metody statyczne - Są to funkcje, które są wspólne dla całej klasy. Oni robią nie działają na instancjach, ale tylko na właściwościach statycznych.

    class Foo {
        public static function bar() {}
    }
    
  5. Stałe - Klasy rozdzielone klasami. Nie wchodząc tutaj głębiej, ale dodając do kompletności:

    class Foo {
        const BAR = 1;
    }
    

Zasadniczo przechowujemy informacje na temat kontenera klas i obiektów za pomocą "podpowiedzi" statyczny które określają, czy informacje są udostępniane (a zatem statyczne), czy nie (a zatem dynamiczne).

Stan i metody

Wewnątrz metody instancja obiektu jest reprezentowana przez $thiszmienna. Obecny stan tego obiektu istnieje, a mutacja (zmiana) dowolnej właściwości spowoduje zmianę tej instancji (ale nie innych).

Jeśli metoda nazywa się statycznie, to $this zmienna nie jest zdefiniowany. Dzieje się tak, ponieważ nie ma żadnej instancji powiązanej z wywołaniem statycznym.

Ciekawą rzeczą jest tutaj, jak tworzone są wywołania statyczne. Porozmawiajmy więc o tym, jak uzyskujemy dostęp do państwa:

Dostęp do państwa

Skoro mamy ten stan, musimy uzyskać do niego dostęp. Może to trochę skomplikować (lub droga więcej niż trochę), podzielmy więc to na dwa punkty widzenia: spoza instancji / klasy (powiedzmy od normalnego wywołania funkcji lub od zasięgu globalnego) oraz wewnątrz instancji / klasy (z poziomu metody na obiekt).

Z zewnątrz instancji / klasy

Z zewnątrz instancji / klasy nasze reguły są dość proste i przewidywalne. Mamy dwóch operatorów i każdy od razu mówi nam, czy mamy do czynienia z instancją, czy z klasą statyczną:

  • -> - obiekt-operator - To jest zawsze używane, gdy mamy dostęp do instancji.

    $bob = new Person;
    echo $bob->name;
    

    Ważne jest, aby pamiętać, że dzwonienie Person->foo nie ma sensu (od Person jest klasą, a nie instancją). Dlatego jest to błąd analizy.

  • :: - operator zakresu-rozdzielczości - Jest to zawsze używane w celu uzyskania dostępu do właściwości lub metody statycznej Klasy.

    echo Foo::bar()
    

    Dodatkowo możemy wywołać metodę statyczną na obiekcie w ten sam sposób:

    echo $foo::bar()
    

    Jego niezwykle Ważne jest, aby pamiętać, że kiedy to robimy z zewnątrzinstancja obiektu jest ukryta przed bar() metoda. Oznacza to, że jest dokładnie taki sam jak uruchomiony:

    $class = get_class($foo);
    $class::bar();
    

W związku z tym, $this nie jest zdefiniowany w wywołaniu statycznym.

Od wewnątrz instancji / klasy

Tutaj trochę się zmienia. Używa się tych samych operatorów, ale ich znaczenie znacznie się zamazuje.

The obiekt-operator  -> jest nadal używany do wywoływania stanu instancji obiektu.

class Foo {
    public $a = 1;
    public function bar() {
        return $this->a;
    }
}

Dzwonić do bar() metoda włączona $foo (instancja Foo) przy użyciu operatora obiektu: $foo->bar() spowoduje powstanie wersji instancji $a.

Tak właśnie się spodziewamy.

Znaczenie :: operator pomimo zmian. Zależy to od kontekstu połączenia z bieżącą funkcją:

  • W statycznym kontekście

    W statycznym kontekście, wszelkie połączenia wykonane przy użyciu :: będzie również statyczny. Spójrzmy na przykład:

    class Foo {
        public function bar() {
            return Foo::baz();
        }
        public function baz() {
            return isset($this);
        }
    }
    

    Powołanie Foo::bar() zadzwoni do baz() metoda statycznie, a co za tym idzie $this będzie nie być wypełnione. Warto zauważyć, że w najnowszych wersjach PHP (5.3+) będzie to powodować E_STRICT błąd, ponieważ statycznie nazywamy metody niestatyczne.

  • W kontekście instancji

    Z drugiej strony w kontekście instancji wywołania z użyciem :: zależy od odbiorcy połączenia (metoda, do której dzwonimy). Jeśli metoda jest zdefiniowana jako static, wtedy użyje połączenia statycznego. Jeśli nie, przekaże informacje o instancji.

    Tak więc, patrząc na powyższy kod, dzwoniąc $foo->bar() wróci true, ponieważ "statyczne" wywołanie odbywa się wewnątrz kontekstu instancji.

Ma sens? Nie sądzę. To jest mylące.

Krótkotrwałe słowa kluczowe

Ponieważ łączenie wszystkiego za pomocą nazw klas jest dość brudne, PHP udostępnia 3 podstawowe słowa kluczowe "skrót", aby ułatwić rozwiązywanie problemu.

  • self - To odnosi się do aktualnej nazwy klasy. Więc self::baz() jest taki sam jak Foo::baz() w obrębie Foo klasa (jakakolwiek metoda na niej).

  • parent - Odnosi się do rodzica obecnej klasy.

  • static - To odnosi się do wezwanej klasy. Dzięki dziedziczeniu klasy potomne mogą przesłonić metody i właściwości statyczne. Więc nazywając ich używaniem static zamiast nazwy klasy pozwala nam rozstrzygnąć, skąd pochodzi połączenie, a nie aktualny poziom.

Przykłady

Najprostszym sposobem na zrozumienie tego jest rozpoczęcie analizy niektórych przykładów. Wybierzmy klasę:

class Person {
    public static $number = 0;
    public $id = 0;
    public function __construct() {
        self::$number++;
        $this->id = self::$number;
    }
    public $name = "";
    public function getName() {
        return $this->name;
    }
    public function getId() {
        return $this->id;
    }
}

class Child extends Person {
    public $age = 0;
    public function __construct($age) {
        $this->age = $age;
        parent::__construct();
    }
    public function getName() {
        return 'child: ' . parent::getName();
    }
}

Teraz również patrzymy na dziedziczenie. Zignoruj ​​na chwilę, że jest to zły model obiektowy, ale spójrzmy, co się dzieje, gdy gramy z tym:

$bob = new Person;
$bob->name = "Bob";
$adam = new Person;
$adam->name = "Adam";
$billy = new Child;
$billy->name = "Billy";
var_dump($bob->getId()); // 1
var_dump($adam->getId()); // 2
var_dump($billy->getId()); // 3

Tak więc licznik ID jest współdzielony zarówno przez instancje, jak i przez dzieci (ponieważ używamy self aby uzyskać do niego dostęp. Jeśli użyliśmy static, możemy zastąpić go w klasie dziecka).

var_dump($bob->getName()); // Bob
var_dump($adam->getName()); // Adam
var_dump($billy->getName()); // child: Billy

Zauważ, że wykonujemy skrypt Person::getName()  instancja metoda za każdym razem. Ale używamy parent::getName() zrobić to w jednym z przypadków (w przypadku dziecka). To sprawia, że ​​podejście to jest potężne.

Słowo Ostrożnie # 1

Zwróć uwagę, że kontekst wywołania określa, czy instancja jest używana. W związku z tym:

class Foo {
    public function isFoo() {
        return $this instanceof Foo;
    }
}

Nie jest zawsze prawdziwe.

class Bar {
    public function doSomething() {
        return Foo::isFoo();
    }
}
$b = new Bar;
var_dump($b->doSomething()); // bool(false)

Teraz jest naprawdę dziwne tutaj. Dzwonimy do innej klasy, ale do $this to zostaje przekazane do Foo::isFoo() metoda jest instancją $bar.

Może to powodować wszelkiego rodzaju błędy i koncepcyjny WTF-ery. Sugerowałbym więc unikanie tego :: operator z metod instancji na dowolnych słowach oprócz tych trzech wirtualnych słów kluczowych "skrótu" (static, self, i parent).

Słowo Ostrożnie # 2

Zwróć uwagę, że statyczne metody i właściwości są wspólne dla wszystkich. To sprawia, że ​​są to w zasadzie zmienne globalne. Wszystkie te same problemy, które pojawiają się w przypadku globaliów. Tak więc byłbym naprawdę niezdecydowany, aby przechowywać informacje w statycznych metodach / właściwościach, chyba że czujesz się komfortowo z tym, że jest prawdziwie globalny.

Słowo Ostrożnie # 3

Zasadniczo będziesz chciał użyć tego, co nazywa się Late-Static-Binding static zamiast self. Ale zauważ, że to nie to samo, mówiąc "zawsze używaj" static zamiast self jest naprawdę krótkowzroczny. Zamiast tego zatrzymaj się i pomyśl o połączeniu, które chcesz wykonać, i zastanów się, czy chcesz, aby zajęcia dla dzieci były w stanie to zmienić statyczne rozwiązane połączenie.

TL / DR

Szkoda, wróć i przeczytaj. Może być za długi, ale jest tak długi, ponieważ jest to złożony temat

TL / DR # 2

Ok dobrze. W skrócie, self służy do odniesienia aktualna nazwa klasyw klasie, gdzie jako $this odnosi się do bieżącego obiektu instancja. Zauważ, że self jest skrótem kopiuj / wklej. Możesz bezpiecznie zastąpić go nazwą swojej klasy i wszystko będzie działać poprawnie. Ale $this jest zmienną dynamiczną, której nie można ustalić z wyprzedzeniem (a nawet nie może być twoją klasą).

TL / DR # 3

Jeśli używany jest obiekt-operator (->), to ty zawsze wiesz, że masz do czynienia z instancją. Jeśli używany jest operator zasięgu i rozdzielczości (::) potrzebujesz więcej informacji na temat kontekstu (czy jesteśmy już w obiekcie-kontekście? Czy jesteśmy poza obiektem? itp.).


228
2018-06-10 15:21



Słowo Ostrożnie # 1: $ to nie zostanie zdefiniowane podczas wywoływania metody statycznej: 3v4l.org/9kr0e - Mark Achée
Dobrze... $this nie zostaną zdefiniowane, jeśli zastosujesz się do "ścisłych standardów" i nie wywołasz metod statycznie, które nie są zdefiniowane jako statyczne. Widzę wynik tutaj wyjaśniony: 3v4l.org/WeHVM Uzgodnione, naprawdę dziwne. - Mark Achée
Po całkowitym przeczytaniu długiego opisu poczułem się leniwy, by przewinąć wyżej, aby go przegłosować. Po prostu żartowałem, upomniałem się: D. Dzięki temu jest to bardzo przydatne. - Mr_Green
Byłoby miło dodać jasne wyjaśnienie na temat różnicy własności self :: $ i self :: property; Myślę, że to też jest dość mylące - Tommaso Barbugli
WoC # 1 zachowuje się inaczej od PHP 7. Jako Foo::isFoo() nazywa się statycznie, $this nie zostaną zdefiniowane. To moim zdaniem bardziej intuicyjne zachowanie. -- Inne inny wynik jest podane, jeśli Bar miały się przedłużyć Foo. Potem połączenie Foo::isFoo() będzie w rzeczywistości w kontekście instancji (nie dotyczy PHP7). - Kontrollfreak


self (nie $ self) odnosi się do rodzaj klasy, gdzie jako $this odnosi się do prądu instancja klasy. self jest przeznaczony do użycia w statycznych funkcjach składowych, aby umożliwić dostęp do statycznych zmiennych składowych. $this jest używany w niestatycznych funkcjach składowych i jest odwołaniem do instancji klasy, na której wywołano funkcję składową.

Bo this jest obiektem, używasz go jak: $this->member

Bo self nie jest obiektem, to w zasadzie typ, który automatycznie odnosi się do bieżącej klasy, używasz go jak: self::member


109
2017-09-30 07:26





$this-> jest używany w odniesieniu do określonej instancji zmiennych klasy (zmiennych składowych) lub metod.

Example: 
$derek = new Person();

$ derek jest teraz specyficzną instancją Osoby. Każda osoba ma imię i nazwisko, ale $ derek ma określoną imię i nazwisko (Derek Martin). Wewnątrz instancji $ derek możemy odnieść się do tych jako $ this-> first_name i $ this-> last_name

ClassName :: jest używana w odniesieniu do tego typu klasy i jej zmiennych statycznych, metod statycznych. Jeśli to pomaga, możesz mentalnie zastąpić słowo "static" przez "shared". Ponieważ są one udostępniane, nie mogą odnosić się do $ this, co odnosi się do konkretnej instancji (nie udostępnianej). Zmienne statyczne (tj. Statyczne $ db_connection) mogą być współużytkowane przez wszystkie wystąpienia typu obiektu. Na przykład wszystkie obiekty bazy danych współużytkują pojedyncze połączenie (połączenie statyczne $).

Przykład zmiennych statycznych: Udawaj, że mamy klasę bazy danych z jedną zmienną składową: static $ num_connections; Teraz umieść to w konstruktorze:

function __construct()
{
    if(!isset $num_connections || $num_connections==null)
    {
        $num_connections=0;
    }
    else
    {
        $num_connections++;
    }
}

Podobnie jak obiekty mają konstruktory, mają również destruktory, które są wykonywane, gdy obiekt umiera lub jest rozbrajany:

function __destruct()
{
    $num_connections--;
}

Za każdym razem, gdy tworzymy nową instancję, zwiększy ona nasz licznik połączeń o jeden. Za każdym razem, gdy niszczymy lub przestajemy używać instancji, liczba kont połączenia zostanie zmniejszona o jeden. W ten sposób możemy monitorować liczbę wystąpień obiektu bazy danych, który mamy w użyciu:

echo DB::num_connections;

Ponieważ $ num_connections jest statyczne (udostępniane), będzie odzwierciedlało całkowitą liczbę aktywnych obiektów bazy danych. Być może widziałeś tę technikę wykorzystywaną do współdzielenia połączeń bazy danych między wszystkimi instancjami klasy bazy danych. Dzieje się tak, ponieważ utworzenie połączenia z bazą danych zajmuje dużo czasu, dlatego najlepiej jest utworzyć tylko jeden i udostępnić go (nazywa się to wzorcem Singleton).

Można użyć metod statycznych (tj. Publicznych statycznych widoków :: numer_czasu formatu ($ cyfry)), BEZ pierwszej instancji jednego z tych obiektów (tzn. Nie odnoszą się one wewnętrznie do $ this).

Metoda statyczna Przykład:

public static function prettyName($first_name, $last_name)
{
    echo ucfirst($first_name).' '.ucfirst($last_name);
}

echo Person::prettyName($derek->first_name, $derek->last_name);

Jak widać, funkcja statyczna public prettyName nic nie wie o obiekcie. Działa tylko z parametrami, które przekazujesz, jak normalna funkcja, która nie jest częścią obiektu. Po co więc zawracać sobie głowę, jeśli nie moglibyśmy tego zrobić jako części obiektu?

  1. Po pierwsze, dołączanie funkcji do obiektów pomaga utrzymać porządek, dzięki czemu wiesz, gdzie je znaleźć.
  2. Po drugie, zapobiega konfliktom nazw. W dużym projekcie prawdopodobnie twoi programiści stworzą funkcje getName (). Jeśli tworzy się ClassName1 :: getName (), a drugi tworzy ClassName2 :: getName (), nie stanowi to żadnego problemu. Bez konfliktu. Yay statyczne metody!

SAMEGO SIEBIE:: Jeśli kodujesz na zewnątrz obiekt, który ma metodę statyczną, do której chcesz się odwołać, musisz wywołać ją za pomocą nazwy obiektu View :: number_fax_phone ($ numer_telefonu); Jeśli kodujesz wewnątrz obiekt, który ma metodę statyczną, do której chcesz się odnosić, możesz zarówno użyj nazwy obiektu View :: numer_pakietu ($ pn), LUB możesz użyć skrótu self: numer_formatu_telefonu ($ pn)

To samo dotyczy zmiennych statycznych: Przykład: Zobacz :: templates_path versus self :: templates_path

Wewnątrz klasy DB, gdybyśmy odnosili się do statycznej metody jakiegoś innego obiektu, użylibyśmy nazwy obiektu: Przykład: Session :: getUsersOnline ();

Ale jeśli klasa DB chciałaby odwoływać się do własnej zmiennej statycznej, po prostu powiedziałaby "self": Przykład: self :: połączenie;

Nadzieja, która pomaga uporządkować sprawy :)


93
2017-10-22 17:52



Masz $ ronny w swoim drugim akapicie tekstu, ale jeśli się nie mylę, to powinno być $ derek. - James Skemp
Świetna odpowiedź. Chcę tylko zwrócić uwagę, że odwołując się do statycznego atrybutu, należy użyć a $ znak. Na przykład self::$templates_path - henrywright


Od ten wpis na blogu:

  • self odnosi się do obecnej klasy
  • self może być użyty do wywołania funkcji statycznych i odniesienia statycznych zmiennych składowych
  • self może być używany wewnątrz funkcji statycznych
  • self może również wyłączyć zachowanie polimorficzne, omijając tabelę vtable
  • $this odnosi się do bieżącego obiektu
  • $this może być użyty do wywołania funkcji statycznych
  • $this nie należy używać do wywoływania statycznych zmiennych składowych. Posługiwać się self zamiast.
  • $this nie mogą być używane wewnątrz funkcji statycznych

27
2018-05-10 12:00





W PHP używa się słowa kluczowego self w celu uzyskania dostępu do właściwości i metod statycznych.

Problem polega na tym, że możesz wymienić $this->method() z self::method()w dowolnym miejscu, niezależnie od tego, czy method() jest deklarowany jako statyczny lub nie. Którego powinieneś użyć?

Rozważ ten kod:

class ParentClass {
    function test() {
        self::who();    // will output 'parent'
        $this->who();   // will output 'child'
    }

    function who() {
        echo 'parent';
    }
}

class ChildClass extends ParentClass {
    function who() {
        echo 'child';
    }
}

$obj = new ChildClass();
$obj->test();

W tym przykładzie self::who() zawsze wyświetli "rodzica", podczas gdy $this->who() będzie zależeć od klasy obiektu.

Teraz możemy zobaczyć, że self odnosi się do klasy, w której się ją nazywa, podczas gdy $this odnosi się do klasa bieżącego obiektu.

Więc powinieneś używać tylko siebie, kiedy $this jest niedostępna lub gdy nie chcesz, aby klasy potomne nadpisały bieżącą metodę.


23
2017-12-29 13:20





W definicji klasy, $ odnosi się do bieżącego obiektu, podczas gdy self odnosi się do bieżącej klasy.

Konieczne jest odwoływanie się do elementu klasy za pomocą self i odwoływanie się do elementu object za pomocą $ this.

self::STAT // refer to a constant value
self::$stat // static variable
$this->stat // refer to an object variable  

19
2018-05-08 06:58





Oto przykład prawidłowego użycia $ this i self dla niestatycznych   i statyczne zmienne składowe:

<?php
class X {
    private $non_static_member = 1;
    private static $static_member = 2;

    function __construct() {
        echo $this->non_static_member . ' '
           . self::$static_member;
    }
}

new X();
?> 

17
2017-12-06 11:26