Wanneer gebruik je jezelf boven $this?

Wat is in PHP 5 het verschil tussen het gebruik van self en $this?

Wanneer is elk geschikt?


Antwoord 1, autoriteit 100%

Kort antwoord

Gebruik $this om te verwijzen naar de huidige
object. Gebruik self om te verwijzen naar de
huidige klasse. Met andere woorden, gebruik
$this->member voor niet-statische leden,
gebruik self::$member voor statische leden.

Volledig antwoord

Hier is een voorbeeld van correct gebruik van $this en self voor niet-statische en statische lidvariabelen:

<?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();
?>

Hier is een voorbeeld van onjuist gebruik van $this en self voor niet-statische en statische lidvariabelen:

<?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();
?>

Hier is een voorbeeld van polymorfisme met $this voor lidfuncties:

<?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();
?>

Hier is een voorbeeld van het onderdrukken van polymorf gedrag door self te gebruiken voor lidfuncties:

<?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();
?>

Het idee is dat $this->foo() de foo()-lidfunctie aanroept van wat het exacte type van het huidige object ook is. Als het object van het type X is, roept het dus X::foo() aan. Als het object van het type Y is, roept het Y::foo() aan. Maar met self::foo() wordt X::foo() altijd aangeroepen.

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

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


Antwoord 2, autoriteit 41%

Het trefwoord zelf verwijst NIET alleen naar de ‘huidige klas’, in ieder geval niet op een manier die je beperkt tot statische leden. Binnen de context van een niet-statisch lid biedt self ook een manier om de vtable te omzeilen (zie wiki op vtable) voor het huidige object. Net zoals je parent::methodName() kunt gebruiken om de ouderversie van een functie aan te roepen, zo kun je self::methodName() aanroepen om de huidige klassenimplementatie aan te roepen van een methode.

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();

Dit levert het volgende op:

Hallo, ik ben Ludwig de nerd
Tot ziens van Ludwig de persoon

sayHello() gebruikt de aanwijzer $this, dus de vtable wordt aangeroepen om Geek::getTitle() aan te roepen.
sayGoodbye() gebruikt self::getTitle(), dus de vtable wordt niet gebruikt, en Person::getTitle() wordt aangeroepen. In beide gevallen hebben we te maken met de methode van een geïnstantieerd object en hebben we toegang tot de $this-aanwijzer binnen de aangeroepen functies.


Antwoord 3, autoriteit 26%

GEBRUIK self:: NIET, gebruik static::

Er is nog een ander aspect van het zelf: dat is het vermelden waard. Vervelend self:: verwijst naar het bereik op het punt van definitie, niet op het punt van uitvoering. Beschouw deze eenvoudige klasse met twee methoden:

class Person
{
    public static function status()
    {
        self::getStatus();
    }
    protected static function getStatus()
    {
        echo "Person is alive";
    }
}

Als we Person::status() aanroepen, zien we “Person is alive” . Overweeg nu wat er gebeurt als we een klasse maken die hiervan overerft:

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

Als we Deceased::status() aanroepen, verwachten we “Persoon is overleden”, maar wat we zien is “Persoon is in leven”, aangezien de scope de originele methodedefinitie bevat bij het aanroepen van self::getStatus() is gedefinieerd.

PHP 5.3 heeft een oplossing. de static:: resolutie-operator implementeert “late static binding”, wat een mooie manier is om te zeggen dat het gebonden is aan de reikwijdte van de aangeroepen klasse. Verander de regel in status() in static::getStatus() en de resultaten zijn wat je zou verwachten. In oudere versies van PHP zul je een kludge moeten vinden om dit te doen.

Zie PHP-documentatie

Dus om de vraag niet te beantwoorden zoals gevraagd …

$this-> verwijst naar het huidige object (een instantie van een klasse), terwijl static:: verwijst naar een klasse


Antwoord 4, autoriteit 14%

Om echt te begrijpen waar we het over hebben als we het hebben over self versus $this, moeten we ons zowel conceptueel als praktisch verdiepen in wat er aan de hand is. peil. Ik heb niet echt het gevoel dat een van de antwoorden dit op de juiste manier doet, dus hier is mijn poging.

Laten we beginnen met te praten over wat een klasse en een object is.

Klassen en objecten, conceptueel

Dus, wat is een les? Veel mensen definiëren het als een blauwdruk of een sjabloon voor een object. U kunt zelfs meer lezen Over klassen in PHP hier . En tot op zekere hoogte is dat ook wat het is. Laten we naar een klas kijken:

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

Zoals je kunt zien, is er een eigenschap in die klasse genaamd $name en een methode (functie) genaamd sayHello().

Het is erg belangrijk op te merken dat de klasse een statische structuur is. Wat betekent dat de klasse Person, eenmaal gedefinieerd, altijd hetzelfde is, overal waar je ernaar kijkt.

Een object daarentegen is een zogenaamd exemplaar van een klasse. Dat betekent dat we de “blauwdruk” van de klas nemen en deze gebruiken om een ​​dynamische kopie te maken. Deze kopie is nu specifiek gekoppeld aan de variabele waarin deze is opgeslagen. Daarom zijn alle wijzigingen aan een instantie lokaal voor die instantie.

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

We maken nieuwe instanties van een klasse met behulp van de operator new.

Daarom zeggen we dat een klasse een globale structuur is en een object een lokale structuur. Maak je geen zorgen over die grappige -> syntaxis, daar gaan we zo even op in.

Een ander ding waar we het over moeten hebben, is dat we kunnen controleren of een instantie een instanceof is van een bepaalde klasse: $bob instanceof Person die een boolean retourneert als de instantie $bob is gemaakt met behulp van de klasse Person, of een onderliggend item van Person .

Status definiëren

Dus laten we eens kijken wat een klasse eigenlijk bevat. Er zijn 5 soorten “dingen” die een klasse bevat:

  1. Eigenschappen – Beschouw deze als variabelen die elke instantie zal bevatten.

    class Foo {
        public $bar = 1;
    }
    
  2. Statische eigenschappen – Zie deze als variabelen die op klasniveau worden gedeeld. Dit betekent dat ze nooit door elke instantie worden gekopieerd.

    class Foo {
        public static $bar = 1;
    }
    
  3. Methoden – Dit zijn functies die elke instantie zal bevatten (en op instanties zal werken).

    class Foo {
        public function bar() {}
    }
    
  4. Statische methoden – Dit zijn functies die door de hele klas worden gedeeld. Ze werken niet op instanties, maar alleen op de statische eigenschappen.

    class Foo {
        public static function bar() {}
    }
    
  5. Constanten – Klasse opgeloste constanten. Ik ga hier niet dieper in, maar voeg voor de volledigheid toe:

    class Foo {
        const BAR = 1;
    }
    

Dus in feite slaan we informatie op over de klasse en objectcontainer met behulp van “hints” over statisch die aangeven of de informatie wordt gedeeld (en dus statisch) of niet (en dus dynamisch).

Status en methoden

Binnen een methode wordt de instantie van een object vertegenwoordigd door de variabele $this. De huidige staat van dat object is aanwezig, en het muteren (wijzigen) van een eigenschap zal resulteren in een wijziging in die instantie (maar niet in andere).

Als een methode statisch wordt aangeroepen, is de variabele $this niet gedefinieerd. Dit komt omdat er geen instantie is gekoppeld aan een statische oproep.

Het interessante hier is hoe statische oproepen worden gedaan. Dus laten we het hebben over hoe we toegang krijgen tot de staat:

Toegangsstatus

Dus nu we die status hebben opgeslagen, moeten we er toegang toe hebben. Dit kan een beetje lastig worden (of veel meer dan een beetje), dus laten we dit opsplitsen in twee gezichtspunten: van buiten een instantie/klasse (bijvoorbeeld van een normale functieaanroep, of van het globale bereik ), en binnen een instantie/klasse (vanuit een methode op het object).

Van buiten een instantie/klasse

Van de buitenkant van een instantie/klasse zijn onze regels vrij eenvoudig en voorspelbaar. We hebben twee operators en elk vertelt ons onmiddellijk of we te maken hebben met een instantie of een statische klasse:

  • ->object-operator – Dit wordt altijd gebruikt wanneer we een instantie benaderen.

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

    Het is belangrijk op te merken dat het aanroepen van Person->foo geen zin heeft (aangezien Person een klasse is, geen instantie). Daarom is dat een parseerfout.

  • ::scope-resolution-operator – Dit wordt altijd gebruikt om toegang te krijgen tot een statische eigenschap of methode van een klasse.

    echo Foo::bar()
    

    Bovendien kunnen we op dezelfde manier een statische methode op een object aanroepen:

    echo $foo::bar()
    

    Het is uiterst belangrijk op te merken dat wanneer we dit van buitenaf doen, de instantie van het object wordt verborgen voor de bar()-methode. Dit betekent dat het precies hetzelfde is als hardlopen:

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

Daarom is $this niet gedefinieerd in de statische aanroep.

Van binnenuit een instantie/klasse

De dingen veranderen hier een beetje. Dezelfde operatoren worden gebruikt, maar hun betekenis vervaagt aanzienlijk.

De object-operator -> wordt nog steeds gebruikt om de instantiestatus van het object aan te roepen.

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

De methode bar() aanroepen op $foo (een instantie van Foo) met behulp van de object-operator: $foo->bar() resulteert in de instantieversie van $a.

Dus zo verwachten we.

De betekenis van de operator :: verandert echter. Het hangt af van de context van de aanroep van de huidige functie:

  • Binnen een statische context

    Binnen een statische context zijn alle oproepen die worden gedaan met :: ook statisch. Laten we een voorbeeld bekijken:

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

    Als u Foo::bar() aanroept, wordt de methode baz() statisch aangeroepen, en daarom zal $this niet worden bevolkt. Het is vermeldenswaard dat dit in recente versies van PHP (5.3+) een E_STRICT-fout veroorzaakt, omdat we niet-statische methoden statisch aanroepen.

  • Binnen een instantiecontext

    Binnen de context van een instantie zijn aanroepen die worden gedaan met :: echter afhankelijk van de ontvanger van de aanroep (de methode die we aanroepen). Als de methode is gedefinieerd als static, gebruikt deze een statische aanroep. Als dit niet het geval is, wordt de instantie-informatie doorgestuurd.

    Dus, kijkend naar de bovenstaande code, zal het aanroepen van $foo->bar() true retourneren, aangezien de “statische” aanroep plaatsvindt binnen de context van een instantie .

Begrijpelijk? Dacht het niet. Het is verwarrend.

Snelkoppelingszoekwoorden

Omdat het nogal vies is om alles aan elkaar te knopen met behulp van klassenamen, biedt PHP 3 standaard “snelkoppelingen” om het oplossen van het bereik gemakkelijker te maken.

  • self – Dit verwijst naar de huidige klassenaam. Dus self::baz() is hetzelfde als Foo::baz() binnen de klasse Foo (elke methode erop).

  • parent – Dit verwijst naar de ouder van de huidige klas.

  • static – Dit verwijst naar de aangeroepen klasse. Dankzij overerving kunnen onderliggende klassen methoden en statische eigenschappen overschrijven. Dus door ze te bellen met static in plaats van een klassenaam, kunnen we achterhalen waar de oproep vandaan kwam, in plaats van het huidige niveau.

Voorbeelden

De gemakkelijkste manier om dit te begrijpen, is door naar enkele voorbeelden te kijken. Laten we een klas kiezen:

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();
    }
}

Nu kijken we hier ook naar erfenis. Negeer even dat dit een slecht objectmodel is, maar laten we eens kijken wat er gebeurt als we hiermee spelen:

$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

Dus de ID-teller wordt gedeeld door beide instanties en de kinderen (omdat we self gebruiken om toegang te krijgen. Als we static gebruikten, zouden we deze kunnen overschrijven in een kinderklas).

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

Houd er rekening mee dat we elke keer de methode Person::getName() instantie uitvoeren. Maar we gebruiken de parent::getName() om het in een van de gevallen te doen (de onderliggende casus). Dit is wat deze aanpak krachtig maakt.

Waarschuwing #1

Houd er rekening mee dat de aanroepcontext bepaalt of een instantie wordt gebruikt. Daarom:

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

Is niet altijd waar.

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

Nu is het echt raar hier. We roepen een andere klasse aan, maar de $this die wordt doorgegeven aan de methode Foo::isFoo() is de instantie van $bar.

Dit kan allerlei bugs en conceptuele WTF-ery veroorzaken. Dus ik raad ten zeerste aan om de operator :: te vermijden binnen instantiemethoden op alles behalve die drie virtuele “short-cut” trefwoorden (static, self en parent).

Waarschuwing #2

Houd er rekening mee dat statische methoden en eigenschappen door iedereen worden gedeeld. Dat maakt ze in feite globale variabelen. Met alle dezelfde problemen die met globals komen. Dus ik zou echt aarzelen om informatie op te slaan in statische methoden/eigenschappen, tenzij je je er prettig bij voelt dat het echt globaal is.

Waarschuwing #3

Over het algemeen wilt u de zogenaamde Late-Static-Binding gebruiken door static te gebruiken in plaats van self. Maar houd er rekening mee dat ze niet hetzelfde zijn, dus zeggen “gebruik altijd static in plaats van self is echt kortzichtig. Stop in plaats daarvan en denk na over de oproep die u wilt make and think of je wilt dat onderliggende klassen die statische opgeloste aanroep kunnen negeren.

TL/DR

Jammer, ga terug en lees het. Het is misschien te lang, maar het is zo lang omdat dit een complex onderwerp is

TL/DR #2

Ok, prima. In het kort, self wordt gebruikt om te verwijzen naar de huidige klassenaam binnen een klasse, terwijl $this verwijst naar het huidige object instantie . Merk op dat self een snelkoppeling voor kopiëren/plakken is. Je kunt het veilig vervangen door je klasnaam, en het zal prima werken. Maar $this is een dynamische variabele die niet van tevoren kan worden bepaald (en misschien niet eens jouw klas is).

TL/DR #3

Als de object-operator wordt gebruikt (->), dan weet je altijd dat je met een instantie te maken hebt. Als de scope-resolution-operator wordt gebruikt (::), heb je meer informatie over de context nodig (bevinden we ons al in een object-context? Staan we buiten een object? enz.).


Antwoord 5, autoriteit 6%

self (niet $self) verwijst naar het type klasse, terwijl $this verwijst naar de huidige instance van de klas. self is bedoeld voor gebruik in statische lidfuncties om u toegang te geven tot statische lidvariabelen. $this wordt gebruikt in niet-statische lidfuncties en is een verwijzing naar de instantie van de klasse waarop de lidfunctie is aangeroepen.

Omdat this een object is, gebruik je het als volgt: $this->member

Omdat self geen object is, is het in feite een type dat automatisch verwijst naar de huidige klasse, je gebruikt het als volgt: self::member


Antwoord 6, autoriteit 5%

$this-> wordt gebruikt om te verwijzen naar een specifieke instantie van de variabelen van een klasse (lidvariabelen) of methoden.

Example: 
$derek = new Person();

$derek is nu een specifiek exemplaar van Persoon.
Elke persoon heeft een voornaam en een achternaam, maar $derek heeft een specifieke voornaam en achternaam (Derek Martin). Binnen de $derek-instantie kunnen we ernaar verwijzen als $this->first_name en $this->last_name

ClassName:: wordt gebruikt om te verwijzen naar dat type klasse, en zijn statische variabelen, statische methoden. Als het helpt, kun je het woord ‘statisch’ mentaal vervangen door ‘gedeeld’. Omdat ze worden gedeeld, kunnen ze niet verwijzen naar $this, dat verwijst naar een specifieke instantie (niet gedeeld). Statische variabelen (d.w.z. statische $db_connection) kunnen worden gedeeld door alle instanties van een type object. Alle database-objecten delen bijvoorbeeld een enkele verbinding (statische $connection).

Voorbeeld van statische variabelen:
Doe alsof we een databaseklasse hebben met een variabele met één lid: static $num_connections;
Zet dit nu in de constructor:

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

Net zoals objecten constructors hebben, hebben ze ook destructors, die worden uitgevoerd wanneer het object sterft of wordt uitgeschakeld:

function __destruct()
{
    $num_connections--;
}

Elke keer dat we een nieuwe instantie maken, wordt onze verbindingsteller met één verhoogd. Elke keer dat we een instantie vernietigen of stoppen met het gebruiken, wordt de verbindingsteller met één verlaagd. Op deze manier kunnen we het aantal instanties van het database-object dat we in gebruik hebben controleren:

echo DB::num_connections;

Omdat $num_connections statisch is (gedeeld), geeft het het totale aantal actieve database-objecten weer. Je hebt misschien gezien dat deze techniek wordt gebruikt om databaseverbindingen te delen tussen alle instanties van een databaseklasse. Dit wordt gedaan omdat het maken van de databaseverbinding lang duurt, dus het is het beste om er maar één te maken en deze te delen (dit wordt een Singleton-patroon genoemd).

Statische methoden (d.w.z. openbare statische View::format_phone_number($digits)) kunnen worden gebruikt ZONDER eerst een van die objecten te instantiëren (d.w.z. ze verwijzen intern niet naar $this).

Voorbeeld van statische methode:

public static function prettyName($first_name, $last_name)
{
    echo ucfirst($first_name).' '.ucfirst($last_name);
}
echo Person::prettyName($derek->first_name, $derek->last_name);

Zoals je kunt zien, weet de openbare statische functie prettyName niets over het object. Het werkt gewoon met de parameters die u doorgeeft, zoals een normale functie die geen deel uitmaakt van een object. Waarom zouden we ons dan druk maken om het niet als onderdeel van het object te hebben?

  1. Ten eerste helpt het toevoegen van functies aan objecten je om dingen georganiseerd te houden, zodat je weet waar je ze kunt vinden.
  2. Ten tweede voorkomt het naamgevingsconflicten. In een groot project heb je waarschijnlijk twee ontwikkelaars getName()-functies. Als de ene een ClassName1::getName() maakt en de andere ClassName2::getName(), is dat geen enkel probleem. Geen conflict. Yay statische methoden!

ZELF::
Als u buiten het object codeert dat de statische methode heeft waarnaar u wilt verwijzen, moet u het aanroepen met de naam van het object View::format_phone_number($phone_number);
Als u in het object codeert dat de statische methode heeft waarnaar u wilt verwijzen, kunt u ofwel de naam van het object gebruiken View::format_phone_number($pn), OF u kan de self::format_phone_number($pn) snelkoppeling gebruiken

Hetzelfde geldt voor statische variabelen:
Voorbeeld: Weergave::templates_path versus zelf::templates_path

Als we binnen de DB-klasse zouden verwijzen naar een statische methode van een ander object, zouden we de naam van het object gebruiken:
Voorbeeld: Sessie::getUsersOnline();

Maar als de DB-klasse naar zijn eigen statische variabele wilde verwijzen, zou hij gewoon zelf zeggen:
Voorbeeld: zelf::verbinding;

Ik hoop dat dat helpt om dingen op te helderen 🙂


Antwoord 7, autoriteit 2%

Van deze blogpost:

  • self verwijst naar de huidige klasse
  • self kan worden gebruikt om statische functies aan te roepen en naar statische lidvariabelen te verwijzen
  • self kan worden gebruikt binnen statische functies
  • self kan polymorf gedrag ook uitschakelen door de vtable te omzeilen
  • $this verwijst naar het huidige object
  • $this kan worden gebruikt om statische functies aan te roepen
  • $this mag niet worden gebruikt om statische lidvariabelen aan te roepen. Gebruik in plaats daarvan self.
  • $this kan niet worden gebruikt binnen statische functies

Antwoord 8

In PHP gebruik je het sleutelwoord self om toegang te krijgen tot statische eigenschappen en methoden.

Het probleem is dat je $this->method() kunt vervangen door self::method()overal, ongeacht of method() wordt statisch verklaard of niet. Dus welke moet je gebruiken?

Denk aan deze code:

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();

In dit voorbeeld zal self::who() altijd parent uitvoeren, terwijl $this->who() afhangt van de klasse van het object heeft.

Nu kunnen we zien dat self verwijst naar de klasse waarin het wordt aangeroepen, terwijl $this verwijst naar de klasse van het huidige object.

Je moet dus alleen self gebruiken als $this niet beschikbaar is, of als je niet wilt dat afstammelingen de huidige methode overschrijven.


Antwoord 9

Binnen een klassedefinitie verwijst $this naar het huidige object, terwijl self verwijst naar de huidige klasse.

Het is noodzakelijk om naar een klasse-element te verwijzen met behulp van self, en naar een objectelement te verwijzen met behulp van $this.

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

Antwoord 10

Hier is een voorbeeld van correct gebruik van $this en self voor niet-statisch
en statische lidvariabelen:

<?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();
?>

Antwoord 11

Volgens http://www.php.net/manual/ nl/language.oop5.static.php er is geen $self. Er is alleen $this, om te verwijzen naar de huidige instantie van de klasse (het object), en self, die kan worden gebruikt om te verwijzen naar statische leden van een klasse. Het verschil tussen een objectinstantie en een klasse komt hier om de hoek kijken.


Antwoord 12

  • De objectaanwijzer $this naar verwijst naar het huidige object.
  • De klassewaarde static verwijst naar het huidige object.
  • De klassewaarde self verwijst naar de exacte klasse waarin deze is gedefinieerd.
  • De klassewaarde parent verwijst naar de ouder van de exacte klasse waarin deze is gedefinieerd.

Zie het volgende voorbeeld dat overbelasting laat zien.

<?php
class A {
    public static function newStaticClass()
    {
        return new static;
    }
    public static function newSelfClass()
    {
        return new self;
    }
    public function newThisClass()
    {
        return new $this;
    }
}
class B extends A
{
    public function newParentClass()
    {
        return new parent;
    }
}
$b = new B;
var_dump($b::newStaticClass()); // B
var_dump($b::newSelfClass()); // A because self belongs to "A"
var_dump($b->newThisClass()); // B
var_dump($b->newParentClass()); // A
class C extends B
{
    public static function newSelfClass()
    {
        return new self;
    }
}
$c = new C;
var_dump($c::newStaticClass()); // C
var_dump($c::newSelfClass()); // C because self now points to "C" class
var_dump($c->newThisClass()); // C
var_dump($b->newParentClass()); // A because parent was defined *way back* in class "B"

Meestal wil je verwijzen naar de huidige klasse en daarom gebruik je static of $this. Er zijn echter momenten waarop je self nodig hebt, omdat je de originele klasse wilt, ongeacht wat deze uitbreidt. (Zeer, Zeer zelden)


Antwoord 13

Ik geloof dat de vraag niet was of je het statische lid van de klas kunt bellen door ClassName::staticMember te bellen. De vraag was wat het verschil is tussen het gebruik van self::classmember en $this->classmember.

Bijvoorbeeld, beide van de volgende voorbeelden werken zonder fouten, of je nu self:: of $this->

gebruikt

class Person{
    private $name;
    private $address;
    public function __construct($new_name,$new_address){
        $this->name = $new_name;
        $this->address = $new_address;
    }
}
class Person{
    private $name;
    private $address;
    public function __construct($new_name,$new_address){
        self::$name = $new_name;
        self::$address = $new_address;
    }
}

Antwoord 14

self verwijst naar de huidige klasse (waarin het wordt genoemd),

$this verwijst naar het huidige object.
U kunt statisch gebruiken in plaats van zelf.
Zie het voorbeeld:

    class ParentClass {
            function test() {
                    self::which();  // output 'parent'
                    $this->which(); // output 'child'
            }
            function which() {
                    echo 'parent';
            }
    }
    class ChildClass extends ParentClass {
            function which() {
                    echo 'child';
            }
    }
    $obj = new ChildClass();
    $obj->test();

Uitvoer:
ouder
kind


Antwoord 15

Hier is een kleine benchmark (7.2.24 op repl.it):

            Speed (in seconds)  Percentage
$this->     0.91760206222534    100
self::      1.0047659873962     109.49909865716
static::    0.98066782951355    106.87288857386

Resultaten voor 4 000 000 runs. Conclusie: het maakt niet uit. En hier is de code die ik heb gebruikt:

<?php
class Foo
{
  public function calling_this() { $this->called(); }
  public function calling_self() { self::called(); }
  public function calling_static() { static::called(); }
  public static function called() {}
}
$foo = new Foo();
$n = 4000000;
$times = [];
// warmup
for ($i = 0; $i < $n; $i++) { $foo->calling_this(); }
for ($i = 0; $i < $n; $i++) { $foo->calling_self(); }
for ($i = 0; $i < $n; $i++) { $foo->calling_static(); }
$start = microtime(true);
for ($i = 0; $i < $n; $i++) { $foo->calling_this(); }
$times["this"] = microtime(true)-$start;
$start = microtime(true);
for ($i = 0; $i < $n; $i++) { $foo->calling_self(); }
$times["self"] = microtime(true)-$start;
$start = microtime(true);
for ($i = 0; $i < $n; $i++) { $foo->calling_static(); }
$times["static"] = microtime(true)-$start;
$min = min($times);
echo $times["this"] . "\t" . ($times["this"] / $min)*100 . "\n";
echo $times["self"] . "\t" . ($times["self"] / $min)*100 . "\n";
echo $times["static"] . "\t" . ($times["static"] / $min)*100 . "\n";

Antwoord 16

Als self wordt gebruikt met de operator ::, verwijst dit naar de huidige klasse, wat zowel in statische als in niet-statische contexten kan worden gedaan. $this verwijst naar het object zelf. Bovendien is het volkomen legaal om $this te gebruiken om statische methoden aan te roepen (maar niet om naar velden te verwijzen).


Antwoord 17

Ik kwam dezelfde vraag tegen en het simpele antwoord is:

  • $this vereist een instantie van de klasse
  • self:: niet

Telkens wanneer u statische methoden of statische kenmerken gebruikt en ze wilt aanroepen zonder dat een object van de klasse wordt geïnstantieerd, moet u self: om ze aan te roepen, omdat $this altijd vereist dat een object wordt aangemaakt.


Antwoord 18

$this verwijst naar het huidige klasseobject, self verwijst naar de huidige klasse (niet-object). De klasse is de blauwdruk van het object. Dus je definieert een klasse, maar je construeert objecten.

Dus met andere woorden, gebruik self for static en this for none-static members or methods.

ook in het kind/ouderscenario wordt self / parent meestal gebruikt om de klassenleden en methoden van het kind en ouder te identificeren.


Antwoord 19

Bovendien is $this:: nog niet besproken.

Alleen voor informatieve doeleinden, vanaf PHP 5.3 bij het omgaan met geïnstantieerde objecten om de huidige bereikwaarde te krijgen, in tegenstelling tot het gebruik van static::, kan men ook $this:: vind ik leuk.

http://ideone.com/7etRHy

class Foo
{
    const NAME = 'Foo';
    //Always Foo::NAME (Foo) due to self
    protected static $staticName = self::NAME;
    public function __construct()
    {
        echo $this::NAME;
    }
    public function getStaticName()
    {
       echo $this::$staticName;
    }
}
class Bar extends Foo
{
    const NAME = 'FooBar';
    /**
     * override getStaticName to output Bar::NAME
     */
    public function getStaticName()
    {
        $this::$staticName = $this::NAME;
        parent::getStaticName();
    }
}
$foo = new Foo; //outputs Foo
$bar = new Bar; //outputs FooBar
$foo->getStaticName(); //outputs Foo
$bar->getStaticName(); //outputs FooBar
$foo->getStaticName(); //outputs FooBar

Het gebruik van de bovenstaande code is niet gebruikelijk of aanbevolen, maar is alleen bedoeld om het gebruik ervan te illustreren en is meer een ‘wist u dat?’ verwijzend naar de vraag van de originele poster.

Het vertegenwoordigt ook het gebruik van $object::CONSTANT bijvoorbeeld echo $foo::NAME; in tegenstelling tot $this::NAME;


Antwoord 20

Gebruik self als je een methode van een klasse wilt aanroepen zonder een object/instantie van die klasse te maken, en zo RAM (gebruik soms zelf voor dat doel). Met andere woorden, het roept eigenlijk een methode statisch aan. Gebruik this voor objectperspectief.


Antwoord 21

Geval 1: Gebruik self kan worden gebruikt voor klasseconstanten

 klasse klasseA {
   const FIXED_NUMBER = 4;
   zelf::POUNDS_TO_KILOGRAMS
}

Als je het buiten de klas wilt aanroepen, gebruik dan classA::POUNDS_TO_KILOGRAMS om toegang te krijgen tot de constanten

Geval 2: Voor statische eigenschappen

klasse klasseC {
   openbare functie __construct() {
   zelf::$_counter++; $this->num = zelf::$_counter;
  }
}

Antwoord 22

Volgens php.net zijn er drie speciale trefwoorden in deze context: self, parent en static. Ze worden gebruikt om toegang te krijgen tot eigenschappen of methoden vanuit de klassendefinitie.

$this daarentegen wordt gebruikt om een ​​instantie en methoden van elke klasse aan te roepen, zolang die klasse maar toegankelijk is.


Antwoord 23

self:: keyword gebruikt voor de huidige klasse en wordt in principe gebruikt om toegang te krijgen tot statische leden, methoden en constanten. Maar in het geval van $this kun je het statische lid, de methode en de functies niet aanroepen.

Je kunt het trefwoord self:: in een andere klasse gebruiken en toegang krijgen tot de statische leden, methode en constanten. Wanneer het wordt uitgebreid van de bovenliggende klasse en hetzelfde in het geval van $this trefwoord. U hebt toegang tot de niet-statische leden, methode en functie in een andere klasse wanneer deze wordt uitgebreid vanuit de bovenliggende klasse.

De onderstaande code is een voorbeeld van self: en $this trefwoorden. Kopieer en plak de code in uw codebestand en bekijk de uitvoer.

class cars{
    var $doors=4;   
    static $car_wheel=4;
  public function car_features(){
    echo $this->doors." Doors <br>";
    echo self::$car_wheel." Wheels <br>"; 
  }
}
class spec extends cars{
    function car_spec(){
        print(self::$car_wheel." Doors <br>");
        print($this->doors." Wheels <br>");
    }
}
/********Parent class output*********/
$car = new cars;
print_r($car->car_features());
echo "------------------------<br>";
/********Extend class from another class output**********/
$car_spec_show=new spec;
print($car_spec_show->car_spec());

LEAVE A REPLY

Please enter your comment!
Please enter your name here

one + seventeen =

Other episodes