Qual é a diferença entre usar self
e static
no exemplo abaixo?
class Foo
{
protected static $bar = 1234;
public static function instance()
{
echo self::$bar;
echo "\n";
echo static::$bar;
}
}
Foo::instance();
produz
1234
1234
Respostas:
Quando você usa
self
para se referir a um membro da classe, está se referindo à classe na qual usa a palavra-chave. Nesse caso, suaFoo
classe define uma propriedade estática protegida chamada$bar
. Quando você usaself
naFoo
classe para se referir à propriedade, está fazendo referência à mesma classe.Portanto, se você tentou usar
self::$bar
em outro lugar em suaFoo
classe, mas tinha umaBar
classe com um valor diferente para a propriedade, ela usaria emFoo::$bar
vez deBar::$bar
, o que pode não ser o que você pretende:Quando você chama um método via
static
, está invocando um recurso chamado late bindings estáticos (introduzido no PHP 5.3).No cenário acima, usar
self
resultará emFoo::$bar
(1234). E usarstatic
resultará emBar::$bar
(4321) porque comstatic
, o interpretador leva em consideração a redeclaração dentro daBar
classe durante o tempo de execução.Normalmente, você usa vinculações estáticas tardias para métodos ou até mesmo para a própria classe, em vez de propriedades, visto que não costuma redeclarar propriedades em subclasses; um exemplo de uso da
static
palavra - chave para invocar um construtor de ligação tardia pode ser encontrado nesta questão relacionada: Novo self vs. novo estáticoNo entanto, isso não impede o uso
static
com propriedades também.fonte
<?php class Foo { public static $bar = 1234; public static function a( ) { echo 'static'.static::$bar; echo 'self'.self::$bar; } } class Bar extends Foo { public static $bar = 4321; } (new Bar())->a(); ?>
self::$abc
quando usado por dentroclass Foo
é o mesmo que dizerFoo::$abc
. Não será afetado por nenhuma nova declaração de$abc
em uma subclasse. AFAIK, a única razão para usarself
é como abreviação, para evitar o uso do nome da classeFoo
, que pode ser mais longo. [Isso também significa que você pode mudar o nome da classe sem mudar todos aqueles lugares - mas isso não é muito motivo, IMHO.] (A escolha de nomes do PHP é lamentável e parece ao contrário; "estático" é o que pode mudar - que é o oposto do significado coloquial da palavra de linguagem natural "estático".)Conforme mencionado, uma das principais diferenças é que
static
permite ligações estáticas atrasadas. Um dos cenários mais úteis que encontrei foi para a criação de classes base para classes singleton:Usar
return static::$name
na classe Base retornará o que foi anexado estaticamente quando foi estendido. Se você fosse usar,return self::$name
entãoB::getName()
retornaria uma string vazia, pois é isso que é declarado na classe Base.fonte
Com
self
chamada:Você pode ver acima, embora tenhamos sobrescrito o
$var
com nossaBar
classe, ele ainda retorna123
, porque pedimos explicitamente ao PHP pelaself
variável, que por sua vez pedeFoo
a variável s.Agora, se trocarmos a chamada com
static
, obteremos, em vez disso,Bar
o valor substituído:Com
static
chamada:fonte