Ir para o conteúdo

Classes em PHP 5

Vamos avançar para a Programação Orientada a Objectos, mais vulgarmente chamada de classes. As classes ou objectos são blocos de código com variáveis e métodos próprios.

Para que servem

A programação orientada a objectos destina-se essencialmente para agrupar informação num objecto, com isso tornamos o código muito mais limpo e centralizado.

Importante: Em PHP não é obrigatório usar POO, e não é uma forma nem mais, nem menos correcta de programar.

Vantagens

  • Reutilização de código
  • Interacção com outros objectos
  • Toda a programação passa de "linhas de código" a "Objectos instanciados"
  • Rapidez na alteração/melhoria de código

Exemplo prático

Se queremos, por exemplo, lêr as informações de clientes a partir de uma base de dados de uma forma constante, alternando apenas no conteúdo. Tendo o objecto instanciado, e um IDE que suporte auto-complete, conseguimos aumentar a velocidade de desenvolvimento visto que passamos de arrays infindáveis sem auto-complete (as keys normalmente teriam de ser colocadas manualmente) a objectos que podemos facilmente distinguir e completar.

Criar a Classe

class nome_da_classe {
//conteúdo da classe
}

Instanciar a Classe

include('nome/da/classe.php'); //deve de estar sempre presente o ficheiro onde se encontra a classe.

$oClasse = new nome_da_classe();

Carregar de forma automática Classes

function __autoload($className) {
    //define-se o ficheiro de origem de uma forma facil substituido _ por /
    $sFileName = str_replace('_',DIRECTORY_SEPARATOR,$className);

    //certifica-se que o ficheiro existe e que a classe não foi declarada
    if (file_exists($sFileName) && !class_exists($sFileName))
        include($sFileName);
}//end of __autoload

Métodos Mágicos

Os métodos mágicos são todos os métodos que são tratados de uma maneira especial pelo PHP porque são os únicos que o próprio PHP chama automaticamente quando apropriado. Isso não significa que o utilizador não os possa chamar, o que é verdade para métodos como o __construct(), só significa que eles têm um significado especial no PHP e que cada um deles têm um propósito especial numa classe. Existem vários métodos mágicos sendo que todos eles começam por __. Por isso, é boa ideia não termos métodos que comecem com __ (dois underscores) na nossa classe a não ser que sejam estes mágicos com o propósito que é suposto terem. Existem vários destes métodos. A destacar:

  • __construct()
    O método que é usado pelo PHP quando se executa um new. Numa classe que estende outra deve chamar este método diretamente a partir do construtor. Nunca se deve chamar este método para criar uma nova instância da classe.
    $obj = new MyObject();
    
  • __toString()
    O método que é usado pelo PHP quando se tenta converter para string.
    echo $obj;
    
  • __clone()
    O método que é usado pelo PHP quando se tenta clonar o objeto. Só é preciso declarar se tivermos atributos que não são clonáveis através da atribuição ($a = $b). Que são, por enquanto, só os objetos.
    class Clonable{
        private $objAttr
        function __clone(){
            $this->objAttr= clone $this->objAttr;
        }
    }
    $obj = new MyObject();
    

Aceder a Métodos

Para acedermos aos métodos e variáveis de uma classe, precisamos de ter instânciado a classe. Para lhes acedermos devemos usar o nome da variável à qual a classe foi instanciada.

//Aqui ele irá fazer o output do que a variável nome_da_funcao() returnar.
echo $oClasse->nome_da_funcao();
//Aqui fará o output do conteúdo da variável $nome_da_variavel.
echo $oClasse->$nome_da_variavel;

Clonar Objectos

Em PHP5 as variáveis não guardam o conteúdo de um objecto, mas apenas uma referência ao objecto em memória. Assim, se atribuirmos o conteúdo de uma variável a outra, ficamos apenas com mais uma referência do mesmo objecto. Exemplo:

class classe_um {
    public $xpto;
}

$objecto_um = new classe_um();
$objecto_um->xpto = "Antes\n";
echo $objecto_um->xpto;         //Resultado: Antes

$objecto_dois = $classe_um;
$objecto_dois->xpto = "Depois\n";

echo $objecto_um->xpto;         //Resultado: Depois

Como vemos, o valor da propriedade xpto do objecto_um foi alterado, embora no código apenas o valor do objecto_dois tenha sido declarado.

Para fazer uma verdadeira clonagem (de forma a que fiquem dois objectos distintos, cada um referenciado por uma variável), é necessário utilizar a palavra-chave clone. Exemplo:

class classe_um {
    public $xpto;
}

$objecto_um = new classe_um();
$objecto_um->xpto = "Antes\n";
echo $objecto_um->xpto;         //Resultado: Antes

$objecto_dois = clone $classe_um;
$objecto_dois->xpto = "Depois\n";

echo $objecto_um->xpto;         //Resultado: Antes

Agora o valor da propriedade xpto do objecto_um mantém-se apesar de termos alterado o valor do objecto_dois, pois são objectos independentes.

Página do manual sobre clonagem de objectos: http://us2.php.net/manual/en/language.oop5.cloning.php

Métodos interceptores

Métodos interceptores ou "overwrites" são usados principalmente para criar de uma forma dinâmica métodos e variáveis. Estes métodos são invocados sempre que uma variável ou método não exista, ou não se encontre pública. Obrigatoriamente todos os métodos interceptores deverão estar definidos como públicos e nunca poderão ser passados por referência.

Intercepção de variáveis

class OverwriteVariables
{
    //Array que irá guardar todas as variáveis dinamicas
    private $aStringAgregator = array();

    //Esta variavel como está declarada não será afectada pelos metodos
    public $nDeclaredVariable = 1;

    //Define uma dada variável dinâmica com um valor
    public function __set($key, $value) {
        echo('Definiu a variável  "'.$key.'" com o valor "'.$value.'"<br>');
        $this->aStringAgregator[$key] = $value;
    }
    //Retorna uma dada variável 
    public function __get($key) {
        echo('A retornar a variável  "'.$key.'"<br>');
        if (isset($this->aStringAgregator[$key]))
           return  $this->aStringAgregator[$key];

        return null;
    }

    //verifica se uma variavel dinamica foi definida
    public function __isset($key) {
        echo('A verificar se a variável "'.$key.'" está definida');
        return isset($this->aStringAgregator[$key]);
    }

    //Remove uma variavel dinamica
    public function __unset($key) {
        echo('A Apagar a variável  "'.$key.'"');
        unset($this->aStringAgregator[$key]);
    }
}