Pergunta

No PHP 5, o que é a diferença entre usar self e $this?

Quando é cada apropriado?

Foi útil?

Solução

Resposta Curta

Use $this para se referir ao atual objeto. Use self para se referir ao classe atual. Em outras palavras, o uso $this->member para membros não-estáticos, uso self::$member para membros estáticos.

Resposta completa

Aqui está um exemplo de correta uso de $this e self para não-estático e variáveis ??membro estático:

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

Aqui está um exemplo de incorreta uso de $this e self para não-estático e variáveis ??membro estático:

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

Aqui está um exemplo de polimorfismo com $this para funções de membro:

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

Aqui está um exemplo de suprimindo o comportamento polimórfico usando self para funções de membro:

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

A idéia é que $this->foo() chama a função de membro foo() de qualquer que seja o tipo exato do objeto atual. Se o objeto for de type X, ele chama assim X::foo(). Se o objeto for de type Y, ele chama Y::foo(). Mas com self :: foo (), X::foo() é sempre chamado.

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

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

Outras dicas

O auto palavra-chave faz não referem-se apenas à 'classe atual', pelo menos não de uma forma que restringe aos membros estáticos. Dentro do contexto de um membro não-estático, self também fornece uma maneira de contornar o vtable ( ver wiki em vtable ) para o objeto atual. Assim como você pode usar parent::methodName() de chamar a versão pais de uma função, então você pode chamar self::methodName() para chamar a corrente aulas implementação de um método.

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

A saída será:

Olá, eu sou Ludwig o geek
Adeus de Ludwig a pessoa

sayHello() usa o ponteiro $this, de modo que o vtable é invocado para chamar Geek::getTitle(). sayGoodbye() usa self::getTitle(), de modo que o vtable não é usado, e Person::getTitle() é chamado. Em ambos os casos, estamos lidando com o método de um objeto instanciado, e ter acesso ao ponteiro $this dentro das funções chamadas.

Não use self::, uso static::

Há um outro aspecto do self :: que vale a pena mencionar. Irritantemente self:: refere-se ao âmbito no ponto de definição, não no ponto de execução . Considere esta classe simples com dois métodos:

class Person
{

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

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

}

Se chamarmos Person::status() veremos "pessoa está viva". Agora, considere o que acontece quando fazemos uma classe que herda esta:

class Deceased extends Person
{

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

}

Chamando Deceased::status() que seria de esperar para ver "Pessoa é falecido", no entanto o que vemos é "pessoa está viva", como o escopo contém a definição do método original quando chamada para self::getStatus() foi definido.

PHP 5.3 tem uma solução. static:: implementos operador de resolução "de ligação estática atrasada" que é uma maneira elegante de dizer que ele está vinculado ao alcance da classe chamada. Altere a linha em status() para static::getStatus() e os resultados são o que você esperaria. Em versões mais antigas do PHP você terá que encontrar um truque para fazer isso.

Documentação Veja PHP

Assim, para responder à pergunta não como pediu ...

$this-> refere-se ao objecto corrente (um exemplo de uma classe), ao passo que static:: refere-se a uma classe

Para realmente entender o que estamos falando quando falamos de self contra $this, precisamos realmente cavar o que está acontecendo em um nível prático conceitual e. Eu realmente não sinto qualquer uma das respostas fazer isso de forma adequada, então aqui está a minha tentativa.

Vamos começar por falar sobre o que um class e um objeto é.

classes e objetos, Conceitualmente

Então, o é a class ? Um monte de pessoas defini-lo como um modelo ou template para um objeto. Na verdade, você pode ler mais Sobre classes em PHP Aqui . E até certo ponto isso é o que ele realmente é. Vamos olhar uma classe:

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

Como você pode dizer, há uma propriedade em que classe chamada $name e um método (função) chamado sayHello().

de muito importante notar que o class é uma estrutura estática. O que significa que o Person classe, uma vez definida, é sempre a mesma em todos os lugares que você olhar para ele.

Um objeto por outro lado, é o que é chamado de exemplo de uma classe. O que isto significa é que tomamos o "projeto" da classe, e usá-lo para fazer uma cópia dinâmica. Esta cópia é agora especificamente ligado à variável é armazenado em. Portanto, quaisquer alterações a um exemplo é local para essa instância.

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

Nós criamos novas casos de uma classe usando o operador new.

Por isso, dizemos que uma classe é uma estrutura global, e um objeto é uma estrutura local. Não se preocupe com que a sintaxe engraçado ->, nós estamos indo para ir para que em um pouco.

Uma outra coisa que deveríamos falar, é que podemos verificação se uma instância é uma instanceof uma classe particular: $bob instanceof Person que retorna um booleano se a instância $bob foi feito usando a classe Person, < em> ou uma criança de Person.

Estado Defining

Então, vamos cavar um pouco sobre o que uma classe realmente contém. Existem 5 tipos de "coisas" que uma classe contém:

  1. Propriedades -. Pense nisso como variáveis ??que cada instância irá conter

    class Foo {
        public $bar = 1;
    }
    
  2. propriedades estáticas - Pense nisso como variáveis ??que são compartilhados no nível da classe. O que significa que eles nunca são copiadas por cada instância.

    class Foo {
        public static $bar = 1;
    }
    
  3. Métodos -. Estas são funções que cada instância conterá (e operam em instâncias)

    class Foo {
        public function bar() {}
    }
    
  4. Métodos estáticos - Estas são funções que são compartilhados por toda a classe. Eles fazem não operar em instâncias, mas em vez disso, as propriedades estáticas somente.

    class Foo {
        public static function bar() {}
    }
    
  5. Constantes - Classe resolvido constantes. Não vai mais fundo aqui, mas a adição de completude:

    class Foo {
        const BAR = 1;
    }
    

Então, basicamente, nós estamos armazenando informações sobre o recipiente de classe e objeto usando "dicas" sobre estática que identificam se a informação é compartilhada (e, portanto, estática) ou não (e, portanto, dinâmico).

Métodos estaduais e

Dentro de um método, instância de um objeto é representado pela variável $this. O estado atual do objeto está lá, e mutação (mudar) qualquer propriedade irá resultar em uma mudança a essa instância (mas não outros).

Se um método é chamado estaticamente, a variável $this não está definido . Isso ocorre porque não há nenhuma instância associada com uma chamada estática.

O interessante aqui é como as chamadas estáticas são feitas. Então, vamos falar sobre como podemos acessar o estado:

Estado Acessando

Portanto, agora que temos armazenados nesse estado, é preciso acessá-lo. Isso pode ficarum pouco complicado (ou modo mais de um bit), então vamos dividir isso em dois pontos de vista: do lado de fora de uma instância / classe (digamos, de uma chamada de função normal, ou do âmbito global), e dentro de uma instância / classe (a partir de dentro de um método no objecto).

Do lado de fora de uma instância / Class

Do lado de fora de uma instância / aula, as nossas regras são bastante simples e previsível. Temos dois operadores, e cada um diz-nos imediatamente se estamos lidando com uma instância ou uma classe estática:

  • -> - objeto operador -. Esta é sempre usado quando estamos acessando uma instância

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

    É importante notar que chamar Person->foo não faz sentido (desde Person é uma classe, não uma instância). Portanto, isso é um erro de análise.

  • :: - escopo de resolução de-operador -. Esta é sempre usado para aceder a uma propriedade de classe estática ou método

    echo Foo::bar()
    

    Além disso, podemos chamar um método estático em um objeto da mesma maneira:

    echo $foo::bar()
    

    de extremamente importante notar que quando fazemos isso a partir do exterior , instância do objeto é escondido do método bar(). O que significa que ele é exatamente o mesmo que executar:

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

Portanto, $this não está definido na chamada estática.

From Inside de uma instância / Class

As coisas mudam um pouco aqui. Os mesmos operadores são usados, mas seu significado torna-se significativamente turva.

O objeto operador -> ainda é usado para fazer chamadas para o estado da instância do objeto.

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

Chamar o método bar() em $foo (uma instância de Foo) usando o objeto-operador:. $foo->bar() resultará na versão da instância de $a

Então é assim que nós esperamos.

O significado do operador :: embora alterações. Depende do contexto da chamada para a função atual:

  • Dentro de um contexto estático

    Dentro de um contexto estático, todas as chamadas feitas usando :: também será estático. Vamos olhar um exemplo:

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

    Chamando Foo::bar() irá chamar o método baz() estaticamente, e, portanto, $this vai não ser preenchido. É importante notar que nas versões recentes do PHP (5.3+), este irá disparar um erro E_STRICT, porque estamos chamando métodos não-estáticos estaticamente.

  • Dentro de um contexto instância

    Dentro de um contexto instância, por outro lado, as chamadas feitas usando :: dependem do receptor da chamada (o método que estamos chamando). Se o método é definido como static, então ele vai usar uma chamada estática. Se não for, ele vai encaminhar as informações exemplo.

    Então, olhando para o código acima, chamando $foo->bar() voltará true, desde a chamada "static" acontece dentro de um contexto de instância.

sentido FAZER? Não penso assim. É confuso.

Short-Cut Palavras-chave

Como amarrar tudo em conjunto, utilizando nomes de classe é bastante sujo, PHP fornece 3 palavras-chave básicas "atalho" para fazer âmbito resolver mais fácil.

  • self - Refere-se ao nome da classe atual. Então self::baz() é o mesmo que Foo::baz() dentro da classe Foo (qualquer método nele).

  • parent - Refere-se ao pai da classe atual.

  • static - Refere-se à classe chamada. Graças à herança, as classes criança pode substituir métodos e propriedades estáticas. Então, chamando-os usando static em vez de um nome de classe nos permite resolver onde a chamada veio, ao invés do nível atual.

Exemplos

A maneira mais fácil de entender isso é começar a olhar para alguns exemplos. Vamos escolher uma 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();
    }
}

Agora, estamos também olhando herança aqui. Ignorar por um momento que este é um modelo de objeto ruim, mas vamos olhar para o que acontece quando jogamos com esta:

$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

Assim, o contador de ID é compartilhado entre ambas as instâncias e os filhos (porque nós estamos usando self para acessá-lo. Se usássemos static, poderíamos substituí-lo em uma classe infantil).

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

Note que estamos executando a Person::getName() exemplo método de cada vez. Mas nós estamos usando o parent::getName() fazê-lo em um dos casos (o caso da Criança). Isto é o que torna esta abordagem poderosa.

Word Of Cuidado # 1

Note que o contexto de chamada é o que determina se uma instância é usado. Portanto:

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

Não é sempre true.

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

Agora é realmente estranho aqui. Nós estamos chamando uma classe diferente, mas o $this que é passada para o método Foo::isFoo() é a instância de $bar.

Isso pode causar todos os tipos de insetos e conceitual WTF-ery. Então, eu gostaria altamente sugiro evitar o operador :: de dentro métodos de instância em qualquer coisa, exceto aquelas três palavras-chave virtuais "de atalho" (static, self e parent).

Word Of Cuidado # 2

Note que os métodos estáticos e propriedades são compartilhadas por todos. Isso os torna variáveis ??basicamente globais. Com todos os mesmos problemas que vêm com globals. Então, eu ficaria muito hesitante para armazenar informações em métodos / propriedades a menos que você está confortável com ele que é verdadeiramente global estáticas.

Word Of Cuidado nº 3

Em geral, você vai querer usar o que é conhecido como Late-Static-Binding usando static vez de self. Mas nota que eles não são a mesma coisa, assim dizendo "use sempre static vez de self é realmente míope. Em vez disso, parar e pensar sobre a chamada que você quer fazer e acho que se você quiser classes filhas para ser capaz de substituir essa estática resolvido chamada.

TL / DR

Muito ruim, voltar e lê-lo. Ele pode ser muito longo, mas é muito tempo, porque este é um tema complexo

TL / DR nº 2

Ok, tudo bem. Em suma, self é utilizado para fazer referência o nome de classe de corrente dentro de uma classe, onde como $this refere-se ao objecto actual exemplo . Note-se que self é um copy / paste de atalho. Você pode seguramente substituí-lo com o nome da classe, e ele vai funcionar bem. Mas $this é uma variável dinâmica que não pode ser determinado antes do tempo (e não podem sequer ser a sua classe).

TL / DR nº 3

Se o objeto-operador é usado (->), então você sempre sabe que está lidando com uma instância. Se o escopo de resolução de-operador é usado (::), você precisa de mais informações sobre o contexto (estamos em um objeto de contexto já? Será que estamos fora de um objeto? Etc).

self (não $ self) refere-se ao tipo de aula, onde, como $this refere-se ao corrente exemplo da classe. self é para uso em funções de membro estático para permitir que você variáveis ??de membro de acesso estáticos. $this é utilizada em funções membro não-estáticos, e é uma referência para o exemplo da classe em que a função de membro foi chamado.

Porque this é um objeto, você usá-lo como: $this->member

Porque self não é um objeto, é basicamente um tipo que se refere automaticamente para a classe atual, você usá-lo como: self::member

$this-> é utilizado para se referir a uma instância específica de um variáveis ??de classe (variáveis ??membros) ou métodos.

Example: 
$derek = new Person();

$ Derek é agora um exemplo específico de pessoa. Cada pessoa tem um first_name e last_name, mas $ Derek tem uma first_name e last_name (Derek Martin) específico. Dentro do exemplo $ Derek, podemos nos referir àqueles quanto $ this-> first_name e $ this-> last_name

ClassName :: é usado para se referir a esse tipo de classe, e suas variáveis ??estáticas, métodos estáticos. Se ajudar, você pode mentalmente substituir a palavra "estática" com "compartilhada". Porque eles são compartilhados, eles não podem se referir a $ this, que se refere a uma instância específica (não compartilhada). Variáveis ??estáticos (ou seja estática $ db_connection) podem ser compartilhados entre todas as instâncias de um tipo de objeto. Por exemplo, todos os objetos de banco de dados compartilhem uma única conexão ($ conexão estática).

<> fortes Variáveis ??estáticas Exemplo: Fingir que temos uma classe de banco de dados com uma única variável de membro: $ num_connections estáticos; Agora, colocar isso no construtor:

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

Assim como objetos ter construtores, eles também têm destruidores, que são executadas quando as matrizes de objeto ou é desactivado:

function __destruct()
{
    $num_connections--;
}

Toda vez que criar uma nova instância, vai aumentar o nosso contador de conexão por um. Toda vez que destruir ou parar de usar uma instância, ele irá diminuir o contador de conexão por um. Desta forma, podemos monitorar o número de instâncias do objeto de banco de dados que temos em uso com:

echo DB::num_connections;

Porque $ num_connections é estático (compartilhado), ele irá refletir o número total de objetos de banco de dados ativos. Você pode ter visto esta técnica usada para conexões de banco de dados share entre todas as instâncias de uma classe de banco de dados. Isso é feito porque a criação da conexão de banco de dados leva um longo tempo, por isso é melhor para criar apenas um, e compartilhá-lo (isso é chamado um padrão Singleton).

Os métodos estáticos (ou seja public static View :: format_phone_number ($ dígitos)) pode ser usado sem primeiro instanciação desses objetos (ou seja, eles não se referem internamente para $ this).

estático Método Exemplo:

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

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

Como você pode ver, a função public static prettyName não sabe nada sobre o objeto. É só trabalhar com os parâmetros que você passa dentro, como uma função normal que não é parte de um objeto. Por que se preocupar, então, se pudéssemos tê-lo não como parte do objeto?

  1. Em primeiro lugar, anexando funções a objetos ajuda a manter as coisas organizadas, assim você sabe onde encontrá-los.
  2. Em segundo lugar, evita conflitos de nomenclatura. Em um projeto grande, é provável que você tem dois desenvolvedores criar funções getName (). Se alguém cria um ClassName1 :: getName (), eo outro cria ClassName2 :: getName (), não é nenhum problema em tudo. Sem conflito. métodos estáticos Yay!

AUTO :: Se você está codificando fora o objeto que tem o método estático que você deseja consultar, você deve chamá-lo usando o nome View :: format_phone_number do objeto ($ phone_number); Se você está codificando dentro o objeto que tem o método estático que você deseja consultar, você pode qualquer usar o nome View :: format_phone_number do objeto ($ pn), ou você pode usar o self :: format_phone_number ($ pn) atalho

O mesmo vale para variáveis ??estáticas: Exemplo: View :: templates_path contra self :: templates_path

Dentro da classe DB, se estavam se referindo a um método estático de algum outro objeto, que usaria o nome do objeto: Exemplo: Sessão :: getUsersOnline ();

Mas se a classe DB queria referir-se a sua própria variável estática, que seria apenas dizer self: Exemplo: self :: conexão;

Espero que ajude esclarecer as coisas:)

A partir este post :

  • self refere-se à classe atual
  • self pode ser usado para funções de chamada estáticos e variáveis ??de membro estático de referência
  • self pode ser usado dentro de funções estáticas
  • self também pode desativar o comportamento polimórfico ignorando o vtable
  • $this refere-se ao objeto atual
  • $this pode ser usado para funções de chamada estática
  • $this não deve ser usado para chamar variáveis ??membro estático. Use self vez.
  • $this não pode ser usado dentro de funções estáticas

Em PHP, você usa o auto palavra-chave para propriedades estáticas de acesso e métodos.

O problema é que você pode substituir $this->method() com self::method()anywhere, independentemente se method() é declarada como estática ou não. Então, qual deles você deve usar?

Considere este código:

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

Neste exemplo, self::who() sempre output ‘pai’, enquanto $this->who() vai depender do que classe o objeto tem.

Agora podemos ver que a auto refere-se à classe em que ele é chamado, enquanto $this refere-se à classe do objeto atual .

Assim, você deve usar a auto somente quando $this não estiver disponível, ou quando você não quer permitir classes descendentes para substituir o método atual.

Dentro de uma definição de classe, $ this refere-se ao objeto atual, embora a auto refere-se à classe atual.

É necessário referir a um elemento de classe usando self, e referem-se a um elemento de objeto usando $ this.

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

Aqui está um exemplo de uso correto de $ this e auto para não-estático e variáveis ??de membro estático:

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

De acordo com a http://www.php.net/manual /en/language.oop5.static.php não há $self. Há apenas $this, para se referir à instância atual da classe (o objeto), e eu, que pode ser usado para se referir a membros estáticos de uma classe. A diferença entre uma instância de objeto e uma classe entra em jogo aqui.

self refere classe atual (em que ele é chamado),

$this refere-se objeto atual. Você pode usar estático em vez de self. Veja o exemplo:

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

Saída: parente criança

  • O ponteiro objeto $ this para se refere ao objeto atual.
  • O valor de classe "estático" se refere ao objeto atual.
  • O valor de classe "eu" refere-se à classe específica foi definido em.
  • O valor de classe "pai" refere-se ao pai da classe exata que foi definido na.

Veja o seguinte exemplo que mostra a sobrecarga.

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

Na maioria das vezes você quer para se referir à classe atual é por isso que você usa static ou $this. No entanto, há momentos em que você necessidade self porque você quer a classe original, independentemente do que estende-lo. (Muito, muito raramente)

Como ninguém aqui falou sobre performances, aqui está uma pequena referência eu fiz (5.6):

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

Esses são os resultados para 2 000 000 corridas, e aqui está o código que usei:

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

Eu acredito questão não era se você pode chamar o membro estático da classe chamando ClassName::staticMember. Pergunta era qual é a diferença entre usar self::classmember e $this->classmember.

Por exemplo, ambos os exemplos a seguir funcionam sem erros, se você usar 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;
    }
}

Quando self é usado com o operador :: que se refere à classe atual, que pode ser feito tanto em estática e contextos não-estáticos. $this refere-se ao próprio objecto. Além disso, é perfeitamente legal usar $this para chamar métodos estáticos (mas não para se referir a campos).

$this refere-se ao objeto da classe atual, self refere-se à classe atual (Não objeto). A classe é o modelo do objeto. Então você definir uma classe, mas você construir objetos.

Assim, em outras palavras, o uso self for static e this for none-static members or methods.

também na criança / pai cenário self / parent é usado principalmente para os membros e métodos identificados criança e classe pai.

Além disso, desde $this:: ainda não foi discutido.

Para fins informativos, a partir do PHP 5.3 quando se lida com objetos instanciados para obter o valor actual âmbito de aplicação, em vez de usar static::, pode-se usar como alternativa $this:: assim.

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

Usando o código acima não é comum ou prática recomendada, mas é simplesmente para ilustrar seu uso, e é agir como mais um "Você sabia?" em referência à pergunta do autor original.

Também representa o uso de $object::CONSTANT por exemplo echo $foo::NAME; em oposição a $this::NAME;

Corri para a mesma pergunta e a resposta é simples:

  • $ this requer uma instância da classe
  • self :: não

Sempre que você estiver usando métodos estáticos ou atributos estática e quiser chamá-los sem ter um objeto da classe instanciado você precisa usar self :: para chamá-los, porque $ this requer sempre no objeto a ser criado.

Use self se você quiser chamar um método de uma classe sem criar um objeto / instância dessa classe, poupando RAM (às vezes usam auto para o efeito). Em outras palavras, é realmente chamar um método estático. Use this para a perspectiva do objeto.

Caso 1: Use self pode ser usado para constantes de classe

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

Se você quiser chamá-lo fora da classe, o uso classA::POUNDS_TO_KILOGRAMS para acessar as constantes

Caso 2: Para propriedades estáticas

class classC {
     public function __construct() { 
     self::$_counter++; $this->num = self::$_counter;
   }
}

De acordo com php.net há três palavras-chave especiais neste contexto: self, parent e static. Eles são usados ??para acessar propriedades ou métodos de dentro da definição de classe.

$this, por outro lado, é usado para chamar uma instância e métodos de qualquer classe, desde que essa classe está acessível.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top