Late Static Binding e o PHP 5.3

Tuesday, May 19, 2009
By Augusto Pascutti

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

Tags: , ,

7 Responses to “Late Static Binding e o PHP 5.3”

  1. Hahaha curti a função norris()!

    #1734
  2. Como nada é perfeito, deram um jeito em um problema e criaram outro ;-)

    #1743
  3. Lucas

    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.

    #2021
  4. 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 …..

    #2038
  5. Falta um echo em cada instrução do método norris()

    #2185
  6. 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 …

    #2225

Leave a Reply