Late Static Binding e o PHP 5.3
Foi lançado a alguns dias a RC2 (release candidate 2) da nova major version do PHP, a versão 5.3. Em alguns dias o PHPSPCast sobre PHP 5.3 deve ir ao ar, mas enquanto ele não chega, vamos entender um pouco mais sobre o problema de Late Static Binding que foi resolvido no PHP 5.3.
O Problema
Eu já tentei explicar conceitualmente, mas, sinceramente? Ninguém entendeu (comigo incluso). Então vamos pra prática. Vamos supor que tenhamos as duas classes abaixo:
class User {
public static function getTipo() {
return 'user';
}
public static function showTipo() {
echo self::getTipo();
}
}
class Admin extends User {
public static function getTipo() {
return 'admin';
}
}
Admin::showTipo(); // imprime: 'user'
A linha 17 do código acima deveria retornar ‘admin’ e não ‘user’ como foi retornado. Esse seria o comportamente esperado. O problema é a palavra reservada self não resolve a chamada estática, assim como a contante __CLASS__ que se for usada, também retorna a classe errada. Ambos não resolvem a chamada em tempo de execução, eles somente verificam ondem foram declaradas e retornam isso.
A solução
A solução não é nenhuma mágica, ou seja, o código não se resolverá sozinho. Quem sabe um dia? A partir da versão 5.3 que será lançada este ano, você poderá usar uma palavra reservada do PHP (que não é nova) e ela – ao contrário do self – irá resolver a chamada em tempo de execução e retornará os valores corretos. A palavra é: static. Sugestivo não?
class User {
public static function getTipo() {
return 'user';
}
public static function showTipo() {
echo static::getTipo();
}
}
class Admin extends User {
public static function getTipo() {
return 'admin';
}
}
Admin::showTipo(); // imprime: 'admin' (PHP 5.3)
Com a troca do self pelo static, o PHP consegue resolver a classe que chamou o método e retornar o valor correto.
O problema (A revolta dos que não foram)
Magicamente, a solução no PHP 5.3 apresenta um (pasme) novo problema. Antes tínhamos o problema (Late Static Binding) de que o PHP não resolvia a classe que chamava o método, o PHP só via em chamadas estáticas o local onde ele foi declarado. Agora nosso problema passa a ser que o PHP não consegue mais ver corretamente chamadas de classes pai, veja o código abaixo e tire suas próprias conclusões.
class User {
public static function getTipo() {
return 'user';
}
public static function showTipo() {
echo static::getTipo();
}
}
class Moderador extends User {
public static function getTipo() {
return 'mod';
}
public static function norris() {
User::showTipo();
parent::showTipo();
self::showTipo();
}
}
class Admin extends Moderador {
public static function getTipo() {
return 'admin';
}
}
Admin::norris();
/**
* Imprime
* user
* admin
* admin
*/
Enfim, o PHP 5.3 está chegando com grandes mudanças, é importante ressaltar que esta é uma major release e que muitas coisas devem ser levadas em consideração. O PHP já possui release candidates para você testar, então se você ainda não testou o que está esperando? Se você puder ainda compilar, não esqueça de rodar um `make test` e enviar os dados para o http://qa.php.net/ para que suas estátisticas dos testes efetuados sejam computados; só isso já é uma contribuição para o projeto. Aguardem essa semana o PHPSPCast sobre as novidades do PHP 5.3, e logicamente, vão se preparando para ele.
A documentação do PHP sobre a implementação de Late Static Binding já existe, inclusive em português e pode ser vista aqui: http://br2.php.net/manual/pt_BR/language.oop5.late-static-bindings.php


Hahaha curti a função norris()!
Como nada é perfeito, deram um jeito em um problema e criaram outro ;-)
Só tenho uma coisa a dizer, se Norris quer que retorne admin, mesmo que seja para retornar mod, o PHP irá retornar admin, quem é o PHP para desafiar Norris? Vai que um dia ele sisma de embasbacar com o cara e acaba virando um ASP da vida depois de um randnose kick!
É triste ver como PHP ainda é imaturo quanto a OO.
Lucas …
Falar que PHP é imaturo em relação a OO é extremamente errado. Se for assim, ele é tão imaturo em relação a OO quanto Java, por exemplo …..
São problemas conhecidos, assim como Java possui diversos que devem ser conhecidos pelos programadores. Acontece …..
Falta um echo em cada instrução do método norris()
reinaldo:
o echo ta na função showTipo() …
public static function showTipo() {
echo static::getTipo();
}
acredito q isso possa ser resolvido passando uma variável como parametro
public static function showTipo($method) {
if($method == ‘static’){
echo static::getTipo();
} else {
echo self::getTipo();
}
}
POG??? talvez .. mas como o PHP se comporta com isso ???
apenas a primeira chamada não se altera .. as outras duas ele busca de acordo com o parametro passado …
[...] Late Static Binding: http://phpsp.org.br/2009/05/19/late-static-binding-e-o-php-53/ [...]