PHP 5.3 parte II: Late Static Bindings

Posted on dezembro 12, 2009. Filed under: PHP |

Na primeira parte desta série abordamos a utilização de namespaces. Nessa segunda parte vamos abordar a utilização de “Late Static Bindings” que é um novo recurso incluído à partir da versão 5.3, que por sinal, é muito interessante.
É mais comum o uso de “Late static bindings” em chamadas de métodos staticos em um contexto de herança. Apesar que não ser limitado somente a métodos staticos.

Para melhor entendermos onde se aplica a utilização de “Late static bindings” vamos analisar o código abaixo:

<?php
class A {
  public static function who() {
    echo __CLASS__;
  }
  public static function test() {
    self::who();
  }
}

class B extends A {
  public static function who() {
    echo __CLASS__;
  }
}

B::test();

As referências staticas para a classe corrente, como self:: e __CLASS__, são resolvidas para a classe no qual o método esta definido e não para a classe chamada em tempo de execução, que no caso a acima foi a class B, filha da classe A.
Dessa forma a saída da execução do script php anterior será:

A

Afim de resolver essa limitação foi escolhido uma palavra-chave para que seja possível referenciar a classe que é chamada em tempo de execução ao invés da classe em que o método pertence. A palavra-chave já reservada é static::.

Vamos alterar o script para que possamos acessar o médoto who() na classe B. Perceba que modificamos self:: para static::.

<?php
class A {
  public static function who() {
    echo __CLASS__;
  }
  public static function test() {
    static::who(); // static:: no lugar de ::self
  }
}

class B extends A {
  public static function who() {
    echo __CLASS__;
  }
}

B::test();

Ao executar o script php anterior, o resultado agora é diferente:

B

A resolução de “Late static bindings” não acontece para chamadas staticas completas, usando o nome da classe. Exemplo de uma chamada statica usando o nome completo: A::foo();. Veja o código abaixo:

<?php
class A {
  public static function foo() {
    static::who();
  }
  public static function who() {
    echo __CLASS__."\n";
  }
}

class B extends A {
  public static function test() {
    A::foo(); // Para essa chamada não acontece resolução de Late Static Bindings
    parent::foo();
    self::foo();
  }
  public static function who() {
    echo __CLASS__."\n";
  }
}

class C extends B {
  public static function who() {
    echo __CLASS__."\n";
  }
}
C::test();

Segue o resultado do código acima:

A
C
C

Podemos concluir no exemplo anterior que:

  • A::foo() não acontece a resolução de “Late static bindings”, mesmo usando a palavra-chace static:: dentro da função foo(). O nome da classe exibida é aquela no qual a função who() pertence, ou seja, classe A
  • Para parent::foo() e self::foo() já acontece a resolução de “Late static bindings”. Portanto o nome da classe exibida é aquela que foi chamada em tempo de execução, ou seja, classe C

Make a Comment

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google

Você está comentando utilizando sua conta Google. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s

Liked it here?
Why not try sites on the blogroll...

%d blogueiros gostam disto: