Apenas um FYI, seu primeiro exemplo é uma variável de instância que chama um método estático, o que não é possível porque um método estático faz parte da classe e não é acessível por meio de uma variável de instância.
Joãoeson
você pode excluir o $ this agora, por favor, não funcionará se apenas usar métodos estáticos e nenhuma instância existir.
...mas por que? $ this-> staticMethod () também funciona. Você pode explicar por que self :: staticMethod () é mais correto (se for)?
Ian Dunn
29
@Ian Dunn Simplificando, $thissó existe se um objeto foi instanciado e você só pode usá-lo a $this->methodpartir de um objeto existente. Se você não tem um objeto, mas apenas chama um método estático e nesse método deseja chamar outro método estático na mesma classe, é necessário usá-lo self::. Portanto, para evitar erros em potencial (e avisos estritos), é melhor usar self.
jeroen
1
Obrigado! Em laravel, descobri que estava acidentalmente chamando o método estático em um controlador estendido usando $this, mas o problema não apareceu até o código ser enviado stage. nenhum erro voltou, o valor era justo 0. ter cuidado com isso, o usoself::
De dentro do foo()método, vamos olhar para as diferentes opções:
$this->staticMethod();
Então isso chama staticMethod()como método de instância, certo? Isso não. Isso ocorre porque o método é declarado como public statico intérprete o chamará como método estático e, portanto, funcionará conforme o esperado. Pode-se argumentar que isso torna menos óbvio a partir do código que uma chamada de método estático está ocorrendo.
$this::staticMethod();
Desde o PHP 5.3 você pode usar $var::method()para significar <class-of-$var>::; isso é bastante conveniente, embora o caso de uso acima ainda seja pouco convencional. Isso nos leva à maneira mais comum de chamar um método estático:
self::staticMethod();
Agora, antes de começar a pensar que ::é o operador de chamada estática, deixe-me dar outro exemplo:
self::bar();
Isso será impresso baz = 1, o que significa isso $this->bar()e self::bar()fará exatamente a mesma coisa; isso ::é apenas um operador de resolução de escopo. É lá para fazer parent::, self::e static::trabalho e dar-lhe acesso a variáveis estáticas; como um método é chamado depende de sua assinatura e de como o chamador foi chamado.
self::bar()parece enganador - isso agora está obsoleto? (usando self::para chamar um método de instância em vez de um método estático).
Página
@ToolmakerSteve de que maneira você diria que é enganosa?
Ja͢ck
Logicamente falando, não há selfquando invocar um método estático. Por definição: o método estático pode ser chamado de qualquer lugar e não recebe um parâmetro "self". No entanto, vejo a conveniência dessa phpsintaxe, para que você não precise escrever MyClassName::. Estou acostumado a linguagens de tipo estatico, em que o compilador deve receber todas as variáveis disponíveis no escopo atual, para que (o equivalente a) self::possa ser omitido. Então, apenas um disse self instanceMethod; não há razão para dizer self staticMethod.
Página
15
Esta é uma resposta muito tardia, mas adiciona alguns detalhes às respostas anteriores
Quando se trata de chamar métodos estáticos no PHP de outro método estático na mesma classe, é importante diferenciar entre selfe o nome da classe.
Eu achei isso informativo. Um pequeno detalhe, eu não diria que as outras respostas são "enganosas". Mais preciso dizer que eles são "incompletos"; eles não abordam a questão (não solicitada) do que self::faz no caso (raro) em que um método estático A chama outro método estático B e B foi substituído em uma subclasse. IMHO, é menos confuso restringir a substituição do método aos métodos de "instância"; use essa habilidade com moderação no nível estático. Em outras palavras, os leitores do seu código esperam que o método substitua os métodos de instância (que é a essência da codificação OO), mas não os estáticos.
Home
1
Muito útil e faz sentido que uma extensão da classe não seja a classe original. Portanto, é lógico que selfnão seria usado nesse caso. Você declarou uma classe separada como uma extensão da primeira classe. Usar selfdentro da classe estendida se referiria à classe estendida. Isso não contradiz as outras respostas, mas certamente ajuda a demonstrar o escopo de self.
iyrin
2
Na versão posterior do PHP self::staticMethod();também não funcionará. Irá lançar o erro padrão estrito.
Nesse caso, podemos criar objetos da mesma classe e chamar por objeto
Você pode fazer isso, embora, se fun1não estiver usando self, não seja lógico torná-lo um método de instância. A maneira correta de fazer isso em php é declarar public static function fun1, em seguida, chamar, especificando a classe: Foo::fun1. Estou certo de que essa é a maneira pretendida de corrigir esse erro padrão estrito.
self
vs.$this
): stackoverflow.com/questions/151969/php-self-vs-this #Respostas:
Mais informações sobre a palavra-chave estática.
fonte
$this
só existe se um objeto foi instanciado e você só pode usá-lo a$this->method
partir de um objeto existente. Se você não tem um objeto, mas apenas chama um método estático e nesse método deseja chamar outro método estático na mesma classe, é necessário usá-loself::
. Portanto, para evitar erros em potencial (e avisos estritos), é melhor usarself
.$this
, mas o problema não apareceu até o código ser enviadostage
. nenhum erro voltou, o valor era justo0
. ter cuidado com isso, o usoself::
Vamos supor que esta seja sua classe:
De dentro do
foo()
método, vamos olhar para as diferentes opções:Então isso chama
staticMethod()
como método de instância, certo? Isso não. Isso ocorre porque o método é declarado comopublic static
o intérprete o chamará como método estático e, portanto, funcionará conforme o esperado. Pode-se argumentar que isso torna menos óbvio a partir do código que uma chamada de método estático está ocorrendo.Desde o PHP 5.3 você pode usar
$var::method()
para significar<class-of-$var>::
; isso é bastante conveniente, embora o caso de uso acima ainda seja pouco convencional. Isso nos leva à maneira mais comum de chamar um método estático:Agora, antes de começar a pensar que
::
é o operador de chamada estática, deixe-me dar outro exemplo:Isso será impresso
baz = 1
, o que significa isso$this->bar()
eself::bar()
fará exatamente a mesma coisa; isso::
é apenas um operador de resolução de escopo. É lá para fazerparent::
,self::
estatic::
trabalho e dar-lhe acesso a variáveis estáticas; como um método é chamado depende de sua assinatura e de como o chamador foi chamado.Para ver tudo isso em ação, consulte esta saída do 3v4l.org .
fonte
self::bar()
parece enganador - isso agora está obsoleto? (usandoself::
para chamar um método de instância em vez de um método estático).self
quando invocar um método estático. Por definição: o método estático pode ser chamado de qualquer lugar e não recebe um parâmetro "self". No entanto, vejo a conveniência dessaphp
sintaxe, para que você não precise escreverMyClassName::
. Estou acostumado a linguagens de tipo estatico, em que o compilador deve receber todas as variáveis disponíveis no escopo atual, para que (o equivalente a)self::
possa ser omitido. Então, apenas um disseself instanceMethod
; não há razão para dizerself staticMethod
.Esta é uma resposta muito tardia, mas adiciona alguns detalhes às respostas anteriores
Quando se trata de chamar métodos estáticos no PHP de outro método estático na mesma classe, é importante diferenciar entre
self
e o nome da classe.Tome por exemplo este código:
A saída deste código é:
Isso ocorre porque
self
se refere à classe em que o código está, e não à classe do código do qual está sendo chamado.Se você quiser usar um método definido em uma classe que herda a classe original, precisará usar algo como:
fonte
self::
faz no caso (raro) em que um método estático A chama outro método estático B e B foi substituído em uma subclasse. IMHO, é menos confuso restringir a substituição do método aos métodos de "instância"; use essa habilidade com moderação no nível estático. Em outras palavras, os leitores do seu código esperam que o método substitua os métodos de instância (que é a essência da codificação OO), mas não os estáticos.self
não seria usado nesse caso. Você declarou uma classe separada como uma extensão da primeira classe. Usarself
dentro da classe estendida se referiria à classe estendida. Isso não contradiz as outras respostas, mas certamente ajuda a demonstrar o escopo deself
.Na versão posterior do PHP
self::staticMethod();
também não funcionará. Irá lançar o erro padrão estrito.Nesse caso, podemos criar objetos da mesma classe e chamar por objeto
aqui está o exemplo
fonte
fun1
não estiver usandoself
, não seja lógico torná-lo um método de instância. A maneira correta de fazer isso em php é declararpublic static function fun1
, em seguida, chamar, especificando a classe:Foo::fun1
. Estou certo de que essa é a maneira pretendida de corrigir esse erro padrão estrito.