PHP V5 e Programação Orientada a Objetos
Quando o PHP V5 foi liberado em 2004, foi um grande salto adiante em comparação ao o que o PHP V4 fornecia em relação à programação orientada a objetos (OOP) e design. Incluía diversos aprimoramento necessários, como visibilidade de classe, construtores e destruidores apropriados, sugestões de tipo e uma API de reflexão de classe. Abriu a porta para a programação orientada a objetos avançada em PHP e permitiu a implementação de muitos padrões de design de forma bem mais fácil, juntamente com melhores classes e APIs de design.
No PHP V5.3, muitas inclusões incrementais foram feitas para aprimorar a OOP. Esses aprimoramentos foram na região de inclusões de sintaxe e aprimoramentos de desempenho. Para começar, vamos dar uma olhada nos novos recursos disponíveis com métodos e membros estáticos.
Manipulação de Métodos e Membros Estáticos Aprimorada
Uma inclusão útil feita no PHP V5 foi a capacidade de especificar um método ou membro de uma classe como estático (o PHP V4 suportava acesso estático a métodos e membros da classe, mas não a capacidade de especificar que o método ou membro foi projetado para acesso estático). O acesso estático é útil principalmente para a implementação do padrão de design singleton, onde existe somente uma instância de classe.
O PHP V5.3 incluiu diversos recursos para aprimorar o suporte para membros e métodos estáticos em uma
classe. Primeiro, vamos dar uma olhada em um novo método mágico incluído: __callStatic().
O PHP V5 possui diversos métodos definidos especialmente que podem ser usados dentro de classes conhecidas como métodos mágicos. Quando definido na classe, esses métodos fornecem funcionalidade especial e possibilitam sobrecarga (a capacidade de permitir que um método aceite diferentes tipos de parâmetros) e polimorfismo (a capacidade de permitir que diferentes tipos de dados usem a mesma interface). Eles também abrem a porta para usar diferentes tipos de métodos de programação OOP e projetar padrões com PHP facilmente.
No PHP V5.3, um novo método mágico é incluído: __callStatic(). Isso funciona de
forma semelhante ao método mágico __call() , que foi projetado para tratar de
chamadas de métodos para métodos que não estão definidos nem visíveis na classe. No entanto,
__callStatic() foi projetado para manipulação de chamadas de métodos estáticos, que fornece a
capacidade de melhor projetar a sobrecarga do método. Um exemplo de como usar esse método segue abaixo.
Lista 1. Exemplo de Uso de
__callStatic() vs.
__call()
class Foo {
public static function __callStatic(
$name,
$args
)
{
echo "Called method $name statically";
}
public function __call(
$name,
$args
)
{
echo "Called method $name";
} }
Foo::dog(); // emite a saída "Called method dog statically" $foo = new Foo; $foo->dog(); //
emite a saída "Called method dog"
|
Uma coisa a observar é que o PHP realmente impinge a definição do método __callStatic()
; deve ser público e deve ser declarado estático. De forma semelhante, o método mágico
__call() também deve ser definido como público, assim como todo os métodos mágicos.
Um recurso interessante do PHP é variáveis variáveis. O que isso significa é que você pode usar o valor da string de uma variável para especificar o nome de outra variável. Ou seja, você poderia fazer algo como o que é mostrado abaixo.
Lista 2. Variáveis Variáveis
$x = 'y';
$$x = 'z';
echo $x; // emite a saída 'y'
echo $y; // emite a saída 'z'
echo $$x; // emite a saída 'z'
|
O mesmo conceito pode ser usado com funções ou mesmo métodos de classe, conforme mostrado abaixo.
Lista 3. Nomes Variáveis de Funções e Métodos de Classe
class Dog {
public function bark()
{
echo "Woof!";
}
}
$class = 'Dog' $action = 'bark'; $x = new $class(); // instancia a classe 'Dog' $x->$action(); //
emite a saída "Woof!"
|
Uma novidade do PHP V5.3 é a capacidade de ter o nome da classe quando especificado por uma variável ao fazer uma chamada estática. Isso abre algumas novas possibilidades, conforme mostrado abaixo.
Lista 4. Nomenclatura de Classe Variável
class Dog {
public static function bark()
{
echo "Woof!";
}
}
$class = 'Dog'; $action = 'bark'; $class::$action(); //emite a saída "Woof!"
|
Esta inclusão torna o recurso variáveis variáveis do PHP completo, permitindo que seja usado em praticamente toda situação com PHP.
Vamos dar uma olhada em mais um aprimoramento útil para usar métodos e membros estáticos: ligação estática atrasada.
Uma das coisas mais perturbadoras em relação ao PHP antes da V5.3 era como métodos e membros estáticos
eram tratados. Até agora, as referências estáticas, como aquelas feitas com self ou
__CLASS__, eram resolvidas no escopo da classe na qual a função era definida. O problema é que a
referência estaria incorreta se a classe fosse estendida e a chamada feita da nova classe-filha. A ligação
estática atrasada foi incluída no PHP V5.3 para aliviar esse problema. Para melhor ilustrar, vamos criar uma
classe com um método estático abaixo.
Lista 5. Classe
Foo com Método Estático
test()
class Foo {
protected static $name = 'Foo';
public static function test()
{
return self::$name;
} }
|
Vamos estender essa classe. Vamos redefinir o membro $name nessa classe-filha.
Lista 6. Classe-filha
Bar que Estende a
Classe-pai Foo
class Bar extends Foo
{
protected static $name = 'Bar';
}
|
Fazemos a chamada estática na Lista 7.
Lista 7. Chamada do Método Estático
test()echo Bar::test(); |
A saída dessa chamada seria a string Foo. Isso ocorre porque a referência a
self::$name feita no método test() é feita com a classe
Foo . A ligação ocorre dessa forma, pois é aí que a função é definida.
O PHP V5.3 incluiu a palavra-chave static para permitir que você faça uma
referência com relação à classe atual. Portanto, você irá alterar a classe Foo
acima para usar essa palavra-chave na Lista 8 e verá que Bar , em vez disso,
será a saída.
Lista 8. Usando a Palavra-chave Estática
class Foo {
protected static $name = 'Foo';
public static function test()
{
return static::$name;
} }
class Bar {
protected static $name = 'Bar'; }
echo Bar::test(); // emite a saída 'Bar'
|
Uma coisa a se observar sobre a palavra-chave static é que não funciona da
mesma forma que funciona no contexto não-estático. Isso significa que as regras de herança normais não se
aplicam a chamadas estáticas. A palavra-chave estática tentará simplesmente resolver a chamada na classe
atual em vez da classe na qual a função foi definida. Esse é um ponto importante a ser observado.
Agora que já vimos alguns aprimoramentos com métodos e membros estáticos, vamos dar uma olhada em algumas novas classes incluídas em uma parte muito útil do PHP V5: a Standard PHP Library.
A Standard PHP Library (SPL) é uma coleta de interfaces e classes incluídas no PHP V5 projetado para
solucionar problemas padrão. Esses problemas incluem ter um objeto com capacidade de iteração, permitir que
um objeto comporte-se como se fosse uma array ou implementar uma lista vinculada. A vantagem de usar essas
classes e métodos é que são nativos do PHP, o que significa que são mais rápidos do que se fossem
implementados no próprio PHP. Eles também, em muitas instâncias, permitem que muitas das funções internas do
PHP usem esse objetos diretamente, como a interface do Agente Interativo permite que você use a
construção foreach para interagir no objeto.
O PHP V5.3 inclui algumas classes adicionais na SPL. Uma, a qual fizemos referência anteriormente, é a
implementação de uma lista duplamente vinculada na classe da SPL SplDoublyLinkedList.
É usada por duas outras novas classes da SPL: SplStack, que implementa uma pilha,
e SplQueue, que implementa uma fila.
Vamos dar uma olhada em como você pode usar a classe SplStack para implementar
uma pilha.
Lista 9. Usando
SplStack
$stack = new SplStack();
// colocar alguns novos itens na pilha $stack->push('a'); $stack->push('b'); $stack->push('c');
// consulte quantos itens estão na pilha echo count($stack); // retorna 3
// iterar os itens da pilha foreach ( $stack as $item )
echo "[$item],"; // o acima emite a saída: [c],[b],[a]
// libere um item da pilha echo $stack->pop(); // retorna 'c'
// agora veja quantos itens estão na pilha echo count($stack); // retorna 2
|
A SqlQueue funciona de forma semelhante, mas funciona como uma fila funcionaria (primeiro item para dentro, primeiro item para fora; em vez de último item para dentro, primeiro item para fora, como na pilha). Além disso, existe uma implementação de heap (SplHeap), assim como
uma fila específica e implementações de heap para determinadas situações (SplMinHeap,
SplMaxHeape SplPriorityQueue).
Outra inclusão útil é a classe SplFixedArray , que, como o nome sugere, é uma
implementação de array de tamanho fixo. É, no entanto, bem rápida — na verdade, tão rápida que teve a
avaliação de desempenho determinada em 10 a 30 por centro mais rápida do que a implementação de array
integrada no PHP. Essa aceleração deve-se ao fato de que a array tem um tamanho fixo, não um tamanho
variável como a do PHP padrão e que índices não-numéricos não são permitidos. A Lista 10 mostra como é
usada.
Lista 10.
SplFixedArray
$array = new SplFixedArray(3); $array[0] = 'dog'; $array[1] = 'cat'; $array[2] = 'bird'; $a->setSize(4);
// aumenta o tamanho rapidamente $array[3] = 'mouse'; foreach ( $array as $value )
echo "[$value],";
Output: [dog],[cat],[bird],[mouse]
|
Além disso, algumas novas classes do agente iterativo foram incluídas:
FilesystemIterator e GlobIterator. Elas funcionam da mesma forma que
outras classes do agente iterativo no PHP, mas foram projetadas especialmente para determinadas instâncias.
Uma outra mudança com a SPL é que agora sempre está ativada no PHP V5.3. Em versões anteriores do PHP V5, você poderia desativar a SPL no tempo de compilação, mas, a partir do PHP V5.3, isso não é mais possível.
As novas inclusões na SPL incluem alguma funcionalidade útil no PHP que é de fácil utilização, assim como implementações de estruturas de dados, como listas duplamente vinculadas, pilhas, heaps e filas. Essas classes podem ser usadas para substituir implementações de espaço do usuário que você possa ter, o que obterá maior velocidade e melhor integração com diversas funções e construções do PHP.
Agora que vimos algumas novas inclusões na SPL, vamos ver como a OOP no PHP V5.3 obtêm um desempenho importante e uma melhora de uso de memória com a inclusão de coleta de lixo circular.
Um problema que os desenvolvedores do PHP encontram a partir de um ponto de vista de desempenho é a coleta de lixo. O PHP tem um coletor de lixo bem simples, que basicamente coletará um objeto para o lixo quando não estiver mais no escopo. A maneira de fazer isso internamente é usando um contador de referência, de forma que quando o contador atingir zero (o que significa que nenhuma referência adicional a esse objeto está disponível), o objeto será coletado para o lixo e expurgado da memória.
Isso funciona relativamente bem, mas pode se tornar um problema em situações em que um objeto faz referências a outro em um relacionamento pai-filho. Nessa situação, o contador de referência para esse objeto não é coletado, de forma que a memória usada por esses objetos permaneça na memória não referida e não seja desalocada até o final do pedido. Vamos dar uma olhada em um exemplo de quando ocorre esse problema.
Lista 11. Relacionamento Pai-filho de Classe Não Coletado Corretamente para o Lixo no PHP V5.2 e Anterior
class Parent {
public function __construct()
{
$this->child = new Child($this);
} }
class Child {
public function __construct(
Parent $parent
)
{
$this->parent = $parent;
} }
|
Nessa instância, toda vez que você cria uma instância da classe Parent e, em
seguida, subsequentemente, a instância sai do escopo, a memória nunca é liberada, de forma que o script
crescerá e aumentará o uso da memória. Há algumas soluções de espaço do usuário para esse problema, como
criar um destruidor para a classe pai que liberará o objeto-filho diretamente. Esse destruidor precisaria ser
chamado especificamente antes de desconfigurar a referência da classe-pai. Apesar de fazer tudo isso
funcionar, complica muito o seu código.
No PHP V5.3, o coletor de lixo detectará essas referências circulares e é capaz de liberar a memória usada
por elas, de forma que o uso de memória do PHP permaneça simples enquanto o script é executado. À medida que
cada referência à classe Parent é removida, a referência à classe
Child na classe Parent também será coletada para o lixo.
O PHP percorre um longo caminho no caminho de suporte para programação orientada a objetos, desde o
suporte fraco nos dias do PHP V4 até as inclusões muito aprimoradas no PHP V5 e ajustes com versões
subsequentes. Agora, o PHP V5.3 obteve alguns aprimoramentos interessantes, incluindo aprimoramentos de
sintaxe, como os novos métodos mágicos __callStatic() , chamadas estáticas
dinâmicas, ligação estática atrasada, método estático e suporte a membro. As novas inclusões na SPL com as
implementações de listas duplamente vinculadas, pilhas, heaps e filas, coloca algumas estruturas de dados
comuns à mão e torna-as fáceis de usar. Por fim, o coletor de lixo circular há muito esperado corrige
problemas de memória e desempenho com classes de auto-referência, implementando um coletor de lixo muito
melhorado que libera memória corretamente para essas instâncias circulares. Todos esses recursos tornam o PHP
V5.3 uma linguagem muito mais forte para programação orientada a objetos.
Aprender
-
Continue esta série com "
O que Há de Novo no PHP V5.3, Parte 2,
Parte 3 e
Parte 4.
-
A Zend Developer Zone possui
documentação para funções de gerenciador de memória.
-
Leia "
A PHP V5 migration guide" para aprender como migrar o código desenvolvido no PHP V4 para a V5.
-
"
Connecting PHP Applications to Apache Derby" mostra como instalar e configurar o PHP no Windows®
(algumas etapas são aplicáveis ao Linux®).
-
PHP.net é o recurso central para desenvolvedores de PHP.
-
Verifique a "
Lista de Leitura Recomendada de PHP."
-
Navegue por todo o
conteúdo de PHP em developerWorks.
-
Expanda suas qualificações em PHP verificando, no IBM developerWorks,
Recursos de Projeto PHP.
-
Para ouvir entrevistas e discussões interessantes para desenvolvedores de software, verifique os
podcasts do developerWorks.
-
Usando um banco de dados com PHP? Verifique o
Zend Core para IBM, um ambiente de desenvolvimento e produção pronto, transparente e de fácil instalação
que suporta o IBM DB2 V9.
-
Mantenha-se atualizado com
Eventos Técnicos e Webcasts do developerWorks.
-
Verifique conferências, feiras comerciais, webcasts e outros
Eventos futuros no mundo que sejam de interesse de desenvolvedores de software livre da IBM.
-
Visite
Zona de Software Livre do developerWorks para obter informações extensivas sobre como executar ações, sobre
ferramentas e atualizações de projetos para ajudá-lo a se desenvolver com tecnologias de software livre e
usá-las com produtos IBM.
-
Assista e aprenda sobre as tecnologias IBM e de software livre e funções de produtos gratuitamente
com os Demos
On Demand do developerWorks.
Obter produtos e tecnologias
-
Inove seu próximo projeto de desenvolvimento de software livre com
software de avaliação da IBM, disponível para download ou em DVD.
-
Faça download de
versões de avaliação de produtos IBMe entre em contato com ferramentas de desenvolvimento de aplicativos
e produtos de middleware do DB2®, Lotus®, Rational®, Tivoli®e WebSphere®.
Discutir
-
Participe de
blogs do developerWorks e envolva-se na comunidade developerWorks.
-
Participe do
PHP Forum: Developing PHP applications with IBM Information Management products (DB2, IDS) do developerWorks.