Auto plus de$?

en PHP 5, Quelle est la différence entre l'utilisation de self et $this ?

quand est-ce que chacun est approprié?

1802
demandé sur 7ochem 2008-09-30 10:23:06
la source

22 ответов

Réponse Courte

utilisez $this pour faire référence à l'actuel objet. Utilisez self pour faire référence au classe actuelle. En d'autres termes, l'utilisation $this->member pour les éléments non statiques, utilisez self::$member pour les éléments statiques.

Réponse Complète

voici un exemple de correct usage de $this et self pour les membres non statiques et statiques variables:

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

voici un exemple de incorrect utilisation de $this et self pour les variables membres non statiques et statiques:

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

voici un exemple de polymorphisme avec $this pour les fonctions des membres:

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

voici un exemple de supprimer le comportement polymorphe en utilisant self pour les fonctions de membre:

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

l'idée est que $this->foo() appelle foo() la fonction de membre de whatever >est le type exact de l'objet courant. Si l'objet est type X , il appelle donc X::foo() . Si l'objet est de type Y , il appelle Y::foo() . Mais avec > self:: foo (), X::foo() est toujours appelé.

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

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

1527
répondu John Millikin 2016-07-28 09:04:22
la source

le mot-clé Auto fait pas se référer simplement à la "classe actuelle", au moins pas d'une manière qui vous restreint aux membres statiques. Dans le contexte d'un membre non statique, self fournit également un moyen de contourner le vtable ( voir wiki sur vtable ) pour l'objet courant. Tout comme vous pouvez utiliser parent::methodName() pour appeler la version parents d'une fonction, de sorte que vous pouvez appeler self::methodName() pour appeler l'implémentation des classes actuelles d'une méthode.

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

Ce sera de sortie:

Bonjour, je suis Ludwig le geek
1519220920" Au revoir de Ludwig la personne

sayHello() utilise le pointeur $this , donc le vtable est invoqué pour appeler Geek::getTitle() . sayGoodbye() utilise self::getTitle() , de sorte que le vtable n'est pas utilisé, et Person::getTitle() est appelé. Dans les deux cas, nous avons affaire avec la méthode d'un objet instancié, et d'avoir accès à la $this pointeur dans les fonctions appelées.

712
répondu nbeagle 2014-11-10 11:37:04
la source

ne pas utiliser self:: , utiliser static::

"

il y a un autre aspect de soi:: cela vaut la peine d'être mentionné. self:: renvoie à la portée au point de définition et non au point d'exécution . Considérez cette classe simple avec deux méthodes:

class Person
{

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

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

}

si nous appelons Person::status() nous verrons "la personne est vivante" . Maintenant, pensez à ce qui se passe quand nous faisons classe qui en hérite:

class Deceased extends Person
{

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

}

appel Deceased::status() nous nous attendions à voir "la personne est décédée" cependant ce que nous voyons est "la personne est vivante" car le champ d'application contient la définition originale de la méthode lorsque l'appel à self::getStatus() a été défini.

PHP 5.3 a une solution. le static:: " l'opérateur de résolution met en œuvre "la fixation statique tardive" qui est une façon fantaisiste de dire qu'il est lié à la portée de la classe appelée. Changez la ligne status() en static::getStatus() et les résultats sont ce que vous attendez. Dans les versions plus anciennes de PHP, vous devrez trouver un kludge pour faire cela.

voir documentation PHP

ainsi pour répondre à la question pas comme demandé ...

$this-> se réfère à l'objet courant (une instance d'une classe), tandis que static:: se réfère à une classe

430
répondu Sqoo 2018-07-04 11:01:45
la source

pour vraiment comprendre de quoi nous parlons quand nous parlons de self versus $this , nous devons réellement creuser dans ce qui se passe à un niveau conceptuel et pratique. Je ne pense pas que les réponses soient appropriées, alors voici ma tentative.

commençons par parler de ce qu'est une classe et un objet .

Classes Et Objets, Conceptuellement

alors, qu'est-ce que est a classe ? Beaucoup de gens le définir comme un plan d'action ou un modèle pour un objet. En fait, vous pouvez lire plus sur les Classes en PHP ici . Et dans une certaine mesure, c'est ce qu'il est vraiment. Regardons une classe:

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

comme vous pouvez le voir, il y a une propriété sur cette catégorie appelée $name et une méthode (fonction) appelée sayHello() .

c'est très important de noter que la classe est une structure statique. Ce qui signifie que la classe Person , une fois définie, est toujours la même partout où vous la regardez.

un objet d'un autre côté Est ce qu'on appelle une instance d'une classe. Ce que cela signifie est que nous prenons le "plan directeur" de la de classe, et l'utiliser pour faire une dynamique exemplaire. Cette copie est maintenant spécifiquement liée à la variable dans laquelle elle est stockée. Par conséquent, toute modification à une instance est locale à cette instance.

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

nous créons de nouvelles instances d'une classe utilisant l'opérateur new .

par conséquent, nous dire qu'une Classe est une structure globale, et qu'un Objet est une structure locale. Ne vous inquiétez pas drôle -> syntaxe, nous allons entrer dans cela dans un peu.

une autre chose dont nous devrions parler, c'est que nous pouvons vérifier si une instance est une instanceof une classe particulière: $bob instanceof Person qui renvoie un booléen si l'instance $bob a été faite en utilisant la Person classe, ou un enfant de Person .

La Définition De L'État

alors creusons un peu dans quelle classe contient en fait. Il existe 5 types de "choses" qu'une classe contient:

  1. propriétés - pensez à ces variables que chaque instance contiendra.

    class Foo {
        public $bar = 1;
    }
    
  2. propriétés statiques - pensez à ces variables qui sont partagées au niveau de la classe. Ce qui signifie qu'ils ne sont jamais copiés par chaque instance.

    class Foo {
        public static $bar = 1;
    }
    
  3. méthodes - ce sont des fonctions que chaque instance contiendra (et fonctionnera sur les instances).

    class Foo {
        public function bar() {}
    }
    
  4. méthodes statiques - ce sont des fonctions qui sont partagées dans toute la classe. Ils ne pas fonctionnent sur les instances, mais seulement sur les propriétés statiques.

    class Foo {
        public static function bar() {}
    }
    
  5. constantes - classes constantes résolues. Je ne vais pas plus loin, mais j'ajoute pour être complet:

    class Foo {
        const BAR = 1;
    }
    

donc fondamentalement, nous stockons des informations sur la classe et le conteneur objet en utilisant des "conseils" sur statique qui identifient si l'information est partagée (et donc statique) ou non (et donc dynamique).

état et méthodes

à l'intérieur d'une méthode, l'instance d'un objet est représentée par la variable $this . L'état actuel de cet objet est là, et la mutation (changement) toute propriété entraîne un changement à cette instance (mais pas d'autres).

si une méthode est appelée statique, la" variable n'est pas définie . C'est parce qu'il n'y a aucune instance associée à un appel statique.

ce qui est intéressant ici, c'est la façon dont les appels statiques sont faits. Alors parlons de la façon dont nous accédons à l'état:

État D'Accès

donc maintenant que nous avons stocké cet état, nous devons y accéder. Cela peut devenir un peu délicat( ou way plus qu'un peu), alors divisons cela en deux points de vue: en dehors d'une instance / classe (par exemple à partir d'un appel de fonction normal, ou à partir de la portée globale), et à l'intérieur d'un instance / classe (à partir d'une méthode sur l'objet).

De L'Extérieur D'Une Instance/Classe

de l'extérieur d'une instance / Classe, nos règles sont assez simples et prévisibles. Nous avons deux opérateurs, et chacun nous dit immédiatement si nous avons affaire à une instance ou une classe statique:

  • -> - objet-opérateur - il est toujours utilisé lorsque nous accédons instance.

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

    Il est important de noter que l'appel Person->foo n'a pas de sens (puisque Person est une classe, une instance). Donc, c'est une erreur d'analyse.

  • :: - champ d'application-résolution - opérateur - il est toujours utilisé pour accéder à une propriété ou méthode statique de classe.

    echo Foo::bar()
    

    en Outre, nous pouvons appeler une méthode statique sur un objet de la même manière:

    echo $foo::bar()
    

    c'est extrêmement important de noter que lorsque nous faisons ce de l'extérieur , l'instance de l'objet est cachée de la méthode bar() . Ce qui veut dire que c'est exactement la même chose que courir:

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

par conséquent, $this n'est pas défini dans l'appel statique.

De L'Intérieur D'Un Instance /Classe

les Choses changent un peu ici. Les mêmes opérateurs sont utilisés, mais leur signification est plus floue.

le object-operator -> est encore utilisé pour faire des appels à l'état d'instance de l'objet.

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

appelant la méthode bar() sur $foo (une instance de Foo ) en utilisant l'objet-opérateur: $foo->bar() résultera dans le la version de l'instance de $a .

C'est ce qu'on attend.

la signification de l'opérateur :: change cependant. Il dépend du contexte de l'appel à la fonction actuelle:

  • dans un contexte statique

    dans un contexte statique, tous les appels faits en utilisant :: seront également statiques. Prenons un exemple:

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

    Appel Foo::bar() va appeler le baz() méthode statique, et donc $this sera pas être remplie. Il est intéressant de noter que dans les versions récentes de PHP (5.3+) cela va déclencher une erreur E_STRICT , parce que nous appelons les méthodes non statiques statiquement.

  • dans un contexte d'instance

    dans un contexte d'instance d'autre part, les appels effectués en utilisant :: dépend du récepteur de l'appel (la méthode que nous appelons). Si la méthode est définie comme static , alors il utilisera un appel statique. Si ce n'est pas le cas, il transmettra les informations de l'instance.

    donc, en regardant le code ci-dessus , appeler $foo->bar() retournera true , puisque l'appel" statique " se produit à l'intérieur d'un contexte d'instance.

ça a un sens? Ne crois pas. C'est déroutant.

Coupe Court De Mots-Clés

parce que lier tout ensemble en utilisant des noms de classe est plutôt sale, PHP fournit 3 mots-clés de base" raccourci " pour rendre la résolution de portée plus facile.

  • self - nom de la classe. Ainsi self::baz() est le même que Foo::baz() dans la classe Foo (n'importe quelle méthode sur elle).

  • parent - Il s'agit du parent de la classe actuelle.

  • static - cela se réfère à la classe appelée. Grâce à l'héritage, les classes d'enfants peuvent outrepasser les méthodes et les propriétés statiques. Donc les appeler en utilisant static au lieu d'un nom de classe nous permet de déterminer d'où vient l'appel, plutôt que le niveau actuel.

exemples

la façon la plus facile de comprendre c'est commencer à regarder quelques exemples. Choisissons une classe:

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

maintenant, nous regardons aussi l'héritage ici. Passez un moment que c'est un mauvais modèle d'objet, mais regardons ce qui se passe quand on joue avec ceci:

$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

donc le compteur ID est partagé entre les deux instances et les enfants (parce que nous utilisons self pour y accéder. Si nous utilisions static , nous pourrions l'outrepasser dans un enfant classe.)

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

notez que nous exécutons à chaque fois la méthode Person::getName() instance . Mais nous utilisons le parent::getName() pour le faire dans l'un des cas (le cas de l'enfant). C'est ce qui rend cette approche puissante.

Mise En Garde #1

notez que le contexte d'appel est ce qui détermine si une instance est utilisée. Par conséquent:

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

N'est pas toujours vrai.

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

Maintenant c'est vraiment bizarre ici. Nous appelons une classe différente, mais le $this qui passe à la méthode Foo::isFoo() est l'instance de $bar .

cela peut causer toutes sortes de bugs et de WTF-ery conceptuelle. Donc je suggère fortement d'éviter l'opérateur :: de l'intérieur des méthodes d'instance sur n'importe quoi sauf ces trois virtuels "coupé court" mots-clés ( static , self , et parent ).

Mot De Mise En Garde #2

notez que les méthodes et propriétés statiques sont partagées par tous. Ce qui en fait des variables globales. Avec les mêmes problèmes que les globals. Donc, je serais vraiment hésitant à stocker des informations dans des méthodes/propriétés statiques à moins que vous ne soyez à l'aise avec elle étant vraiment globale.

Mot De Mise En Garde #3

en général, vous voudrez utiliser ce qu'on appelle Late-Static-Binding en utilisant static au lieu de self . Mais notez qu'ils ne sont pas la même chose, donc dire "toujours utiliser static au lieu de self est vraiment myope. Au lieu de cela, arrêtez-vous et pensez à l'appel que vous voulez faire et pensez si vous voulez que les classes pour enfants soient en mesure de passer outre que statique résolu appel.

TL / DR

dommage, retournez la lire. Il peut être trop long, mais c'est long car c'est un sujet complexe

TL / DR #2

Ok, très bien. En bref, self est utilisé pour faire référence à le nom de classe actuel dans une classe, où comme $this se réfère à l'objet actuel instance . Notez que self est un raccourci copier/coller. Vous pouvez le remplacer par votre nom de classe, et ça marchera très bien. Mais $this est une variable dynamique qui ne peut pas être déterminée à l'avance (et peut même ne pas être votre classe).

TL / DR #3

si l'opérateur objet est utilisé ( -> ), alors vous toujours sachez que vous avez affaire à une instance. Si l'opérateur scope-resolution-operator est utilisé ( :: ), vous avez besoin de plus d'informations sur le contexte (sommes-nous déjà dans un contexte objet? Sommes-nous à l'extérieur d'un objet? etc.)

231
répondu ircmaxell 2017-05-23 14:33:26
la source

self (not $self) se réfère au type de la classe, où comme $this se réfère à l'actuelle instance de la classe. self est à utiliser dans les fonctions membres statiques pour vous permettre d'accéder membre statique des variables. $this est utilisé dans les fonctions membres non statiques, et est une référence à l'instance de la classe sur laquelle la fonction membre a été appelée.

parce que this est un objet, vous l'utilisez comme: $this->member

parce que self n'est pas un objet, c'est fondamentalement un type qui se réfère automatiquement à la classe courante, vous l'utilisez comme: self::member

109
répondu MrZebra 2013-05-06 13:49:23
la source

$this-> est utilisé pour désigner une instance spécifique des variables (variables membres) ou des méthodes d'une classe.

Example: 
$derek = new Person();

$derek est maintenant une instance spécifique de personne. Chaque personne a un first_name et un last_name, mais $derek a un first_name et un last_name spécifiques (Derek Martin). Dans l'instance $ derek, nous pouvons nous référer à ceux comme $this - > first_name et $this->last_name

nom de classe:: est utilisé pour se référer à ce type de classe, et ses variables statiques, ses méthodes statiques. Si cela peut aider, vous pouvez mentalement remplacer le mot "statique" avec "partagé". Parce qu'ils sont partagés, ils ne peuvent pas se référer à $this, qui se réfère à une instance spécifique (non partagée). Les Variables statiques (c'est-à-dire static $db_connection) peuvent être partagées entre toutes les instances d'un type d'objet. Par exemple, tous les objets de la base de données partagent une seule connexion ($connection statique).

Exemple De Variables Statiques: Prétendre que nous avons un classe de base de données avec une variable à un seul membre: statique $ num_connections; Maintenant, mettez ceci dans le constructeur:

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

tout comme les objets ont des constructeurs, ils ont aussi des destructeurs, qui sont exécutés lorsque l'objet meurt ou est désactivé:

function __destruct()
{
    $num_connections--;
}

chaque fois que nous créons une nouvelle instance, cela augmentera notre compteur de connexion d'un. Chaque fois que nous détruisons ou arrêtons d'utiliser une instance, cela diminuera le compteur de connexion d'un. Dans ce façon, nous pouvons surveiller le nombre d'instances de l'objet de base de données, nous avons utilisé avec:

echo DB::num_connections;

parce que $num_connections est statique (partagé), il reflétera le nombre total d'objets de base de données actifs. Vous avez peut-être vu cette technique utilisée pour partager des connexions de base de données entre toutes les instances d'une classe de base de données. Cela est fait parce que la création de la connexion de base de données prend beaucoup de temps, il est donc préférable d'en créer une seule, et de la partager (ceci s'appelle un Singleton Modèle.)

Les méthodes statiques

(C'est-à-dire public static View::format_phone_number ($digits)) peuvent être utilisées sans instanciation préalable d'un de ces objets (c'est-à-dire qu'elles ne se réfèrent pas en interne à $this).

Exemple De Méthode Statique:

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

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

comme vous pouvez le voir, la fonction publique statique prettyName ne sait rien sur l'objet. C'est simplement de travailler avec les paramètres que vous passez, comme une fonction normale c'est pas partie d'un objet. Pourquoi s'embêter, alors, si nous pouvions juste l'avoir pas comme partie de l'objet?

  1. premièrement, attacher des fonctions à des objets vous aide à garder les choses organisées, de sorte que vous savez où les trouver.
  2. deuxièmement, il prévient les conflits de noms. Dans un grand projet, vous êtes susceptible d'avoir deux développeurs de créer des getName (). Si L'un crée un ClassName1::getName(), et l'autre crée ClassName2::getName(), ce n'est pas un problème du tout. Aucun conflit. Yay méthodes statiques!

SELF:: Si vous codez à l'extérieur de l'objet qui a la méthode statique à laquelle vous voulez faire référence, vous devez l'appeler en utilisant la vue nom de l'objet:: format_phone_number ($phone_number); Si vous êtes le codage à l'intérieur l'objet qui contient la méthode statique que vous souhaitez consulter, vous pouvez soit utiliser le nom de l'objet View:: format_phone_number ($pn), ou vous pouvez utiliser le self:: format_phone_number ($pn) raccourci

il en va de même pour les variables statiques: Exemple: View::templates_path rapport à soi::templates_path

dans la classe DB, si nous nous référions à une méthode statique d'un autre objet, nous utiliserions le nom de l'objet: exemple: Session:: getUsersOnline ();

mais si la classe DB voulait se référer à sa propre variable statique, il se dirait juste: Exemple: self::connexion;

Hope qui aide à clarifier les choses :)

93
répondu lo_fye 2018-02-16 17:10:47
la source

à Partir de ce blog :

  • self renvoie à la classe actuelle
  • self peut être utilisé pour appeler des fonctions statiques et de référence des variables statiques
  • self peut être utilisé à l'intérieur de fonctions statiques
  • self peut également désactiver le comportement polymorphe en contournant le vtable
  • $this fait référence à l'objet actuel
  • $this peut être utilisé pour appeler des fonctions statiques
  • $this ne doit pas être utilisé pour appeler des variables membres statiques. Utilisez self à la place.
  • $this ne peut pas être utilisé à l'intérieur des fonctions statiques
27
répondu okconfused 2014-01-24 19:46:59
la source

en PHP, vous utilisez le mot-clé self pour accéder aux propriétés statiques et aux méthodes.

le problème est que vous pouvez remplacer $this->method() par self::method() n'importe où, peu importe si method() est déclaré statique ou non. Alors, qui devriez-vous utiliser?

considérez ce 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();

dans cet exemple, self::who() produira toujours" parent", tandis que $this->who() dépendra de la classe de l'objet.

maintenant, nous pouvons voir que self se réfère à la classe dans laquelle il est appelé, tandis que $this se réfère à la classe de l'objet actuel .

ainsi, vous devriez utiliser self seulement quand $this n'est pas disponible, ou quand vous ne voulez pas permettre aux classes descendantes d'écraser la méthode actuelle.

23
répondu ramin rostami 2017-06-28 20:06:03
la source

dans la définition d'une classe, $renvoie à l'objet courant, tandis que self renvoie à la classe courante.

il est nécessaire de faire référence à un élément de classe en utilisant self, et de faire référence à un élément d'objet en utilisant $this.

self::STAT // refer to a constant value
self::$stat // static variable
$this->stat // refer to an object variable  
19
répondu Tarun Singhal 2015-12-14 15:57:19
la source

voici un exemple d'utilisation correcte de $this et self pour non-static et les variables statiques des membres:

<?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
répondu Mohit Bumb 2011-12-06 15:26:22
la source

selon http://www.php.net/manual/en/language.oop5.static.php il n'y a pas de $self . Il n'y a que $this , pour se référer à l'instance courante de la classe (l'objet), et le soi, qui peut être utilisé pour se référer aux membres statiques d'une classe. La différence entre une instance objet et une classe entre en jeu ici.

16
répondu cruizer 2018-02-16 17:10:30
la source

comme personne ici ne parlait de performances, voici un petit benchmark que j'ai fait (5.6):

 Name     | Time    | Percent  
----------|---------|---------  
 $this->  | 0.99163 | 106.23%  
 self::   | 0.96912 | 103.82%  
 static:: | 0.93348 | 100%

ce sont les résultats pour 2 000 000 de passages, et voici le code que j'ai utilisé:

<?php

require '../vendor/autoload.php';

// My small class to do benchmarks
// All it does is looping over every test x times and record the
//   time it takes using `microtime(true)`
// Then, the percentage is calculated, with 100% being the quickest
// Times are being rouned for outputting only, not to calculate the percentages
$b = new Tleb\Benchmark\Benchmark(2000000);

class Foo
{
    public function calling_this()
    {
        $this->called();
    }

    public function calling_self()
    {
        self::called();
    }

    public function calling_static()
    {
        static::called();
    }

    public static function called()
    {
    }
}

$b->add('$this->',  function () { $foo = new Foo; $foo->calling_this(); });
$b->add('self::',   function () { $foo = new Foo; $foo->calling_self(); });
$b->add('static::', function () { $foo = new Foo; $foo->calling_static(); });

$b->run();
12
répondu tleb 2015-10-01 08:04:55
la source

self se rapporte à la classe courante (dans laquelle elle est appelée),

$this renvoie à l'objet courant. Vous pouvez utiliser statique au lieu de l'auto. Voir l'exemple:

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

sortie: parent enfant

12
répondu Kabir Hossain 2018-02-16 17:12:42
la source

je crois que la question n'était pas de savoir si vous pouvez appeler le membre statique de la classe en appelant ClassName::staticMember . La question était de savoir quelle était la différence entre self::classmember et $this->classmember .

pour par exemple, les deux exemples suivants fonctionnent sans aucune erreur, que vous utilisiez self:: ou $this->

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;
    }
}
11
répondu Akintunde-Rotimi 2018-02-16 17:11:20
la source
  • le pointeur d'objet $ceci se réfère à l'objet courant.
  • la valeur de classe" statique " se rapporte à l'objet courant.
  • La classe de la valeur "auto" fait référence exacte de la classe qu'il a été défini.
  • la valeur de classe" parent " se rapporte au parent de la classe exacte dans laquelle il a été défini.

voir l'exemple suivant qui montre une surcharge.

<?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"

la plupart du temps, vous voulez vous référer à la classe courante, c'est pourquoi vous utilisez static ou $this . Cependant, il ya des moments où vous besoin self parce que vous voulez la classe d'origine indépendamment de ce qui l'étend. (Très, très rarement)

10
répondu Xeoncross 2013-03-22 19:30:00
la source

quand self est utilisé avec l'opérateur :: il se réfère à la classe courante, qui peut être fait à la fois dans des contextes statiques et non statiques. $this se réfère à l'objet lui-même. En outre, il est parfaitement légal d'utiliser $this pour appeler des méthodes statiques (mais ne pas faire référence à des champs).

10
répondu mrDjouk 2013-03-22 19:34:05
la source

$this se rapporte à l'objet de la classe courante, self se rapporte à la classe courante (non à l'objet). La classe est le modèle de l'objet. Donc vous définissez une classe, mais vous construisez des objets.

donc, en d'autres termes, utilisez self for static et this for none-static members or methods .

aussi dans le scénario enfant / parent self / parent est principalement utilisé pour identifier les enfants et les parents membres de la classe et les méthodes.

5
répondu Rakesh Singh 2014-09-15 10:36:28
la source

en outre depuis $this:: n'a pas encore été discuté.

à titre d'information seulement, à partir de PHP 5.3 en traitant des objets instanciés pour obtenir la valeur de portée actuelle, par opposition à l'utilisation de static:: , on peut alternativement utiliser $this:: comme ainsi.

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

L'utilisation du code ci-dessus n'est pas une pratique courante ou recommandée, mais est simplement pour illustrer son utilisation, et d'agir plus comme un "le Saviez-vous?"en référence à la question de l'affiche originale.

il représente également l'usage de $object::CONSTANT par exemple echo $foo::NAME; par opposition à $this::NAME;

5
répondu fyrye 2015-10-14 20:02:26
la source

utiliser self si vous voulez appeler une méthode d'une classe sans créer un objet/instance de cette classe, donc sauvegarder RAM (parfois utiliser soi-même à cette fin). En d'autres termes, il appelle en fait une méthode statiquement. Utilisez this pour la perspective de l'objet.

4
répondu minhajul 2018-02-16 17:12:05
la source

Cas 1: L'utilisation de self peut être utilisée pour les constantes de classe

 class classA { 
     const FIXED_NUMBER = 4; 
     self::POUNDS_TO_KILOGRAMS
}

si vous voulez l'appeler en dehors de la classe, utilisez classA::POUNDS_TO_KILOGRAMS pour accéder aux constantes

Case 2: pour les propriétés statiques

class classC {
     public function __construct() { 
     self::$_counter++; $this->num = self::$_counter;
   }
}
1
répondu li bing zhao 2016-02-03 00:14:00
la source

j'ai rencontré la même question et la réponse simple est:

  • $ce nécessite une instance de la classe
  • self:: n'est pas

Chaque fois que vous utilisez méthodes statiques ou les attributs statiques et que vous voulez les appeler sans avoir un objet de la classe instanciée, vous devez utiliser self:: pour les appeler, car $this nécessite toujours que l'objet soit créé.

1
répondu Mike 2018-05-19 18:23:49
la source

selon php.net il y a trois mots clés spéciaux dans ce contexte: self , parent et static . Ils sont utilisés pour accéder aux propriétés ou aux méthodes à partir de la définition de la classe.

$this , d'autre part, est utilisé pour appeler une instance et des méthodes de n'importe quelle classe aussi longtemps que cette classe est accessible.

0
répondu Fil 2015-12-07 15:26:21
la source

Autres questions sur php class scope