Como entender o POO para o PHP

Este artigo é baseado em um artigo que escrevi no ano de 2007 logo após a Borcon 2007, onde falei sobre POO no PHP 5. Tem muito coisa bacana sobre POO no PHP. Vamos a elas!

Nos últimos anos o PHP atingiu o nível de plataforma mais popular da Web estando presente em mais de 1/3 dos servidores Web do mundo e este crescimento não e só em relação quantidade, mas também em relação de qualidade. O nível da plataforma hoje é bastante alto e ela bastante completa, não deixando a desejar a nenhuma outra plataforma ou linguagem existente nos dias atuais.

Porém, isso não foi sempre assim. Acredito, esta é uma opinião pessoal, que Ramus Lerdof não imaginava que o PHP se tornaria o que é hoje. Em 1995 quando criou o PHP/FI (Personal Home Page Tools /- Form Interpreter), ele era apenas uma coleção de scripts Perl que manipulava requisições enviadas por formulários mas ainda lhe faltava muitos recursos.

Em 1997, foi lançada uma revisão do PHP/FI que na época era desenvolvido quase que na sua totalidade por Rasmus sozinho. Foi nesta época que Andi Gutmans e Zeev Zuraski descobriram o PHP/FI quando pesquisavam por uma linguagem para desenvolver um projeto final da faculdade, porém descobriram também que a linguagem não era tão poderosa assim. Foi ai que Zeev a Andi decidiram reescrever totalmente a linguagem de scripts e então formaram uma equipe com Rasmus para lançar ai sim o PHP 3, isso mesmo, PHP como PHP só a partir da versão 3 quando passou a se chamar Hypertext Preprocessor com o intuito de mostrar que esse PHP era diferente, adequado não somente ao uso pessoal.

Foi nesta fase também que eles desenvolveram uma nova API de extensões que possibilitou oferecer suporte a novas extensões de uma maneira mais fácil para realizar tarefas como acessar bases de dados e etc. Foi nesta versão que o PHP ultrapassou a marca de 1.000.000 de domínios.

No final de 1998 Andi e Zeev decidiram revisar o trabalho no PHP 3 e perceberam que podiam ter feito algo melhor e então iniciaram a caminhada em busca do PHP 4. Enquanto o PHP 3 fazia o parsing dos scripts ao mesmo tempo em que os executava o PHP 4 trouxe um novo conceito de “compilar primeiro e executar depois”. Mas não se espante a compilação aqui não é em código de maquina e sim em byte code. Agora a versão 4 possui um novo coração chamado Zend Engine (só por curiosidade Zend significa Zeev e Andi) e com isso a performance do PHP 4 era muito melhor do que a versão 3 e essa era apenas uma das muitas melhorias. Foi nesta versão também que passou a utilizar a o numero da menor versão para indicar mudanças significativas na linguagem como no caso do PHP 4.1.0 que introduziu as surperglobais $_GET e $_POST e PHP 4.3.0 com uma Interface de Linha de Comando (CLI) e uma camada aprimorada de I/O. A ultima versão significativa do PHP 4 foi lançada em 27 de dezembro de 2002.

Logo em seguida a demanda por mais funcionalidades OO aumentou e muito levando Andi a reescrever toda a parte Orientada a Objetos do Zend Engine e junto com Zeev escreveu o documento “Zend Engine II: Feature Overview and Design” e com isso deram início a uma grande discussão sobre o futuro do PHP. A linguagem básica se manteve a mesma, porém novas funcionalidades foram adicionadas outras retiradas e algumas nunca saíram do papel como é o caso da herança múltipla citada no documento e que deu lugar a interfaces. Mecanismos como o SimpleXML coloca o PHP 5 no mesmo nível de outras tecnologias Web em alguns pontos e superar em outros. O PHP 5 traz também novas API’s como SOAP, MYSQL e outras com recursos avançados.

O que há de novo

O tempo sem dúvida nenhuma é o melhor depurador para uma nova tecnologia, é ele que irá dizer se tal tecnologia chegou ou não para ficar. No caso do PHP 5 isso está mais do que “depurado”, está depurado, testado e distribuído. As novas funcionalidades e modificações têm por objetivos eliminar do PHP qualquer falha ou fraqueza para garantir que ele permaneça na liderança como a melhor linguagem para elaboração de scripts do mundo. Entre as principais mudanças e melhorias podemos destacar.

Novo modelo OO

Quando Zeev adicionou “suporte” a orientação a objetos no PHP 3 ele servia apenas para acessar coleções e permitia que uma classe agregasse métodos e propriedades mas era somente isso. Quando eles reescreveram o PHP e implementaram o Zend Engine no PHP 4, eles investiram em melhorar a performance e suporte a API e praticamente abandonaram o modelo OO do PHP 3, porém o uso deste modelo intensamente em grandes aplicações, mesmo com serias limitações, tornou-se o foco principal no PHP 5 e foi isso que fizeram.

Umas das principais limitações em relação a OO no PHP 4 era quanto a cópia dos objetos. Eles eram tratados como tipos comuns, nativos e com isso quando uma variável qualquer recebia uma outra que possuía um objeto na verdade ela recebia uma cópia e isso era desastroso, pois as duas variáveis apontavam para endereços de memória diferentes e com isso levava o programa a comportamentos inesperados de forma que, ao modificar uma não significava modificar a outra. Observe:


class Pessoa{
         var $nome;
        function Pessoa($nome){
            $this->setNome($nome)
        } 

        function getNome(){
             return $this->nome;    
        }

       function setNome($nm){
           $this->nome = $nm;
       }
}

Temos aqui uma classe pessoa com uma propriedade nome e três métodos: o construtor function Pessoa, um método get e um método set para acessar a propriedade. Agora externa a classe vamos criar uma função para alterar o nome de um objeto qualquer:

function AlterarPessoa($Obj, $NovoNome){
        $Obj->setName($NovoNome);
}

Esta função apenas irá mudar o nome do objeto passado como parâmetro, porém observe:


$p = new Pessoa(‘Jose’);
AlterarPessoa($p, ‘Joao’);
echo  $p->getNome();

No PHP 4 o código acima retornaria ‘Jose’ e não ‘Joao’ como esperado, pois $p é passado como valor para função AlteraPessoa e esta trabalha em cima de uma cópia de $p e não no próprio objeto passado. Havia dois tipos de programadores PHP os que sabiam que isso acontecia e outros que não sabiam. No PHP 5 a infra-estrutura do modelo OO foi reescrita adicionando o conceito de handles de objetos, assim quando um objeto era passado como parâmetro na verdade o que era passado era o handle do objeto, um ponteiro.

Escopo de Visibilidade

Foram adicionados alguns modificadores de acessas comuns a OO como private, protected e public e isso para métodos e propriedades. A partir da versão 5 ficou mais simples implementar encapsulamento de métodos e propriedades através destes modificadores:

class MinhaClasse{
        private $codigo = null;
         public setCodigo($id){
            $this->codigo;
        }
}

Obs.: Se nenhum escopo for informado o padrão adotado será o public e por questões de compatibilidade a sintaxe var $nome ainda é valida, porém não recomendada.

Construtor Unificado

Agora há no PHP uma método exclusivo para construtor da classe, trata-se do método __construct() que é usado em vez de uma função com o mesmo nome da classe como era no PHP 4. Por motivos de compatibilidade ainda há suporte a esta operação porem recomenda-se o uso desta última.

class Carro{
        function __construct(){
            echo “Carro Construído”;    
          }    
}

Suporte a Destrutores

Podemos agora ter um método chamado automaticamente quando o objeto é destruído. Este método é o __destruct().

class Carro{
        function __destruct(){
            echo “Carro Destruído”;
         }
}

Interfaces

Foram introduzidas no PHP 5 em lugar da herança múltipla, elas dão as classes a habilidade de atender a mais de um requisito no modelo OO. Cada classe pode herdar somente de uma classe, porém podem implementar quantas interfaces quiser e o melhor há também o suporte a herança entre as interfaces. Entenda a interface como sendo uma espécie de contrato, de regra que toda a classe que a implementar deve seguir, com isso podemos programar em cima de uma interface e não de uma implementação concreta, aumentando assim a abstração e diminuindo o acoplamento.

interface Operacao{
        function executar();
}
class Somar implements Operação{
        public $n1;
        public $n2;
        function executar(){
            return $this->n1+$this->n2;
        }
}
class Subtrair implements Operação{
        public $n1;
        public $n2;
        function executar(){
            return $this->n1-$this->n2;
        }
}

Operador instanceof

No PHP 4 existia uma função chamada is_a() que verificava se o objeto era uma ou pertencia a uma determinada hierarquia de classe. Agora no PHP 5 utilizamos a função instanceof para realizar esta verificação:

if ($Obj instanceof Pessoa) {
        echo “O Objeto verificado e uma Pessoa”;
}

Métodos Finais

A palavra reservada final pode ser adicionada a alguns métodos e com isso impedir que esses métodos sejam sobrescritos em uma classe descendente.

class Cachorro{
        final function Latir(){
            echo “Cachorro Latindo”;
        }
}

Este método não poderá ser sobrescrito numa classe descendente.

Classes Finais

Da mesma maneira que um método uma classe pode ser declarada como final impedindo assim que seja herdada dentro do modelo OO:

final class Carro{  

}
class CarroNacional extends Carro{
} 

O código acima geraria um erro, pois a classe Carro não pode ser herdada.

Clonagem de Objetos

Com o novo modelo OO aquele comportamento indevido de copias de objetos foi corrigido, porém há casos em que se faz necessário a copias de determinados objetos para atender a um requisito de seu modelo. Para esses casos foi adicionada ao PHP 5 a função clone e foi permitido também adicionar uma função __clone() que será invocada todas as vezes que seu objeto for clonado (após as propriedades terem sido copiadas do objeto original).

class Aluno{
        function __clone(){
            echo “Objeto clonado”;
        }
}

$Alunos = new Aluno;
$CopiaAlunos = clone $Alunos;

Constantes de Classes

As classes agora podem possuir constantes que são acessadas através da própria classe:

class Mensagens{
        const Sucesso = “Operação realizada com Sucesso”;
        const Erro = “Um erro ocorreu nesta operação”;
}

echo Mensagens::Sucesso;
echo Mensagens::Erro;

Métodos Estáticos

Agora é possível adicionar métodos estáticos a suas classes e estes serão acessados a partir da classe e não do objeto, isto facilita a implementação de alguns padrões de projeto como é o caso do Singleton por exemplo:

class Conexao{
        static function GetConexao(){
            echo “Conexão realizada”;    
        }        
} 

Conexão::GetConexao();

Propriedades Estáticas

Assim como nos métodos podemos ter agora propriedades estáticas, isto é, propriedades que podem ser acessadas diretamente da classe sem a necessidade de se instanciar o objeto.

class Conexao{
        static private $conection = null;
        static function GetConexao(){
            retun self::$conection;    
        }        
} 
        
Conexão::GetConexao();

Classes Abstratas

Uma classe dita como abstrata não pode ser implementada, porem podem perfeitamente ser herdadas.


abstract class ClasseBase{
        
}

$base = new ClasseBase;

O código acima geraria um erro pois ClasseBase não pode ser instanciada.

Métodos Abstratos

Assim como no caso das classes podemos ter métodos abstratos, isto é, que não possuem definição na classe que o contem ficando isso a cargo da classe que o sobrescreve. Uma classe que possua um método abstrato deve ser declarada como abstrata:

abstract class Base{
        abstract function Executar();
} 

Hints de Classe

Todos sabem que o PHP é fracamente tipado, porem há um recurso que foi adicionado ao PHP 5 que permiti fazer a verificação do tipo da classe nos parâmetros das funções, são as chamadas Dicas de Tipos de classe, que geram um erro caso o parâmetro passado não seja do tipo especificado na dica de tipo de classe:

function Falar(SerHumano $Obj){

}

Onde na função acima SerHumano seja uma classe definida previamente e a função falar só ira aceitar como parâmetro objetos que sejam desta classe ou herdem da mesma.

Tratamento de Exceções

O PHP 5 trás o suporte a tratamentos de exceção através dos comandos try throw catch. Com isso podemos criar rotinas de exceção com classes que herdem da classe Exception nativa no PHP:

Class MinhaExcecao extends Exception{
  public $erro;
  function __construct($erro){
      $this->erro = $erro;
  }
} 
 
try {
       throw new MinhaExcecao(‘Esse e o meu erro !!!’);
}catch(MinhaExcecao $e) {
      echo “Um erro ocorreu com a seguinte mensagem: $e->erro;”
}catch(Exception $e) {
      echo “Um erro genérico ocorreu”;
}

Foreach com Referências

No PHP 4 não era possível varrer um array e modificar seus valores, com o PHP 5 isso é possível basta marcar o loop foreach com um sinal de “&” (referência), que faz com que quaisquer valores que modifique altera o array que você está iterando:

foreach ($array as &$value){
              $value *= 2;   
}

Valor Default por Referência

No PHP 4 valores padrões para os métodos só eram permitidos quando seus parâmetros eram passados por valor, agora há suporte a valores default mesmo que os parâmetros sejam passados por referência:

function referencia(&$param = null){
   if ($params === null){
       echo “parâmetro nulo”;
   }
}

Modificações Gerais

Seguindo as modificações na linguagem a atualização no suporte a XML sem dúvida nenhuma é a mais significante. No PHP 4 o suporte a XML estava dividido em varias bibliotecas cada uma responsável por atender e uma determinada demanda, isso era ruim, pois as funções de manutenção eram pobres e o suporte a novos padrões XML nem sempre podiam ser implementados.

No PHP 5 as extensões foram reescritas para utilizar o kit de ferramentas libxml2 XML. Todas as extensões (SAX, DOM, XSLT, SIMPLEXML e SOAP) utilizam agora a libxml2.

Dentre as extensões acima vale destacar a SIMPLEXML que sem duvida revolucionou a maneira de lidar com arquivos XML. Os desenvolvedores PHP trabalham com arquivos XML como se estivessem trabalhando com Objetos nativos do PHP podendo ler, escrever ou iterar sobre ele com uma facilidade extrema. Observe:


<veiculos>

   <carro>

     <marca>Honda</marca>

     <modelo>Civic</modelo>

  </carro>

  <carro>

     <marca>Toyota</marca>

      <modelo>Corolla</modelo>

   </carro>

</veiculos>



$veiculos = simplexml_load_file(‘carros.xml’);

foreach($veiculos->carro as $carro){

         echo “O carro $carro->modelo é fabricado pela $carro->marca”;

Links Úteis

  • O que é PHP?:
    O PHP (um acrônimo recursivo para PHP: Hypertext Preprocessor) é uma linguagem de script open source de uso geral, muito utilizada, e especialmente adequada para o desenvolvimento web e que pode ser embutida dentro do HTML.
  • Wiki PHP:
    PHP (um acrônimo recursivo para "PHP: Hypertext Preprocessor", originalmente Personal Home Page) é uma linguagem interpretada livre, usada originalmente apenas para o desenvolvimento de aplicações presentes e atuantes no lado do servidor, capazes de gerar conteúdo dinâmico na World Wide Web.
  • Curso de PHP para Iniciantes:
    Neste curso de PHP para iniciantes veremos os princípios de desenvolvimento, como funções nativas do PHP, estruturas de controle, variáveis, orientação a objetos e acesso a banco de dados, sempre utilizando exemplos para explicar cada item.

Saiba mais sobre Java ;)

  • PHP: Utilizando os operadores break e continue:
    Aqui apresentamos as estruturas de controle break e continue. Com elas podemos interromper uma estrutura de repetição ou mover o cursor para a próxima iteração.
  • Documentação: PHP: Modificadores de acesso:
    Neste documento você encontrará o conteúdo que precisa para aprender o que são e para que servem os modificadores de acesso na linguagem PHP.
  • Linguagem PHP:
    Neste Guia de Consulta você encontrará todo o conteúdo que precisa para aprender PHP, uma linguagem de programação amplamente utilizada para a construção de aplicações web.