Há uma série de métodos que podem ser implementados em uma classe com o propósito de ser chamado internamente pelo mecanismo PHP. Estes são conhecidos como métodos mágicos e eles são fáceis de reconhecer como todos eles começam com dois sublinhados. Listados na tabela a seguir são os métodos mágicos:
Nome | Descrição |
__construct(. . .) | Chamado ao criar uma nova instância. |
__destruct() | Chamado quando o objeto não deve mais ter referências. |
__call($name, $array) | Chamado quando invocando métodos inacessíveis em um contexto de objeto. |
__callStatic($name, $array) | Chamado quando invocando métodos inacessíveis em um contexto estático. |
__get($name) | Chamado quando a leitura de dados de propriedades é de difícil acesso. |
__set($name, $value) | Chamado quando a gravação de dados para propriedades inacessíveis. |
__isset($string) | Chamado quando isset ou vazio é usado em propriedades inacessíveis. |
__unset($string) | Chamado quando isset ou vazio é usado em propriedades inacessíveis. |
Além destes, há mais seis métodos mágicos que, como os outros podem ser implementados nas classes para fornecer certas funcionalidades.
Nome | Descrição |
__toString() | Chamado por objeto a conversões de cadeia. |
__invoke(. . .) | Chamado por objeto a conversões de função. |
__sleep() | Chamado por serialize. Executa tarefas de limpeza e retorna um array de variáveis a ser serializado. |
__wakeup() | Chamado por unserialize para reconstruir o objeto. |
__set_state($array) | Chamado por var_export. O método deve ser estático e seu argumento contém as propriedades exportadas. |
__clone() | Chamado depois que objeto tenha sido clonado. |
ToString
Quando um objeto é usado em um contexto onde se espera uma string, a engine do PHP irá procurar por um método nomeado __toString para recuperar uma representação de string do objeto.
class MyClass { public function __toString() { return 'Instance of ' . __CLASS__; } } $obj = new MyClass(); echo $obj; // "Instance of MyClass"
Não é possível definir como um objeto se comporta quando avaliada como outros tipos de string.
Invoke
O método __invoke permite que um objeto possa ser tratado como uma função. Quaisquer argumentos fornecidos quando o objeto é chamado será usado como argumentos da função __invoke MyClass.
class MyClass { public function __invoke($arg) { echo $arg; } } $obj = new MyClass(); $obj('Test'); // "Test"
Serialização de objetos
A serialização é o processo de converter dados em um formato de string. Isso é útil para armazenar objetos em bancos de dados ou arquivos. No PHP, a função serialize realiza esse objeto para conversão de cadeia e unserialize converte a cadeia de volta para o objeto original. A função serialize controla todos os tipos, exceto para o tipo resource, o que, por exemplo, é usado para manter as conexões de banco de dados e manipuladores de arquivo. Considere a seguinte classe de banco de dados simples.
class MyConnection { public $link, $server, $user, $pass; public function connect() { $this->link = mysql_connect($this->server, $this->user, $this->pass); } }
Quando esta classe é serializado a conexão do banco de dados serão perdidos e a variável $link tipo resource segurando a conexão será armazenado como null();.
$obj = new MyConnection(); // ... $bin = serialize($obj); // serialize object $obj = unserialize($bin); // restore object
Para obter maior controle sobre como os dados objeto é serializado e desserializados os métodos __sleep e __wakeup pode ser implementados por esta classe.
Sleep
O método __sleep é chamado por serialize e precisa retornar um array contendo as propriedades que serão serializados. Esse array não deve incluir propriedades privadas ou protegidas, como serialize não será capaz de acessá-los. O método também pode executar tarefas de limpeza antes que ocorra a serialização, como commitar quaisquer dados pendentes para mídias de armazenamento.
public function __sleep() { return array('server', 'user', 'pass'); }
Observe que as propriedades voltou para serializar em forma de string. O tipo de recurso ponteiro $link não está incluído no array, uma vez que não pode ser serializado. Para restabelecer a conexão do banco de dados o método __wakeup pode ser usado.
Wakeup
Chamando unserialize no objeto serializado vai invocar o método __wakeup, a fim de restaurar o objeto. Ele não aceita argumento e não precisa devolver qualquer valor. Ele é usado para restabelecer variáveis tipo de resource e para a realização de outras tarefas de inicialização que podem precisar de ser feito depois que o objeto foi desserializados. Neste exemplo, ele restabelece a conexão do banco de dados MySQL.
public function __wakeup() { if(isset($this->server, $this->user, $this->pass)) $this->connect(); }
Note que a construção isset é chamado aqui com vários argumentos, nesse caso, ele só vai retornar true se todos os parâmetros estão definidos.
Definir Estado
A função var_export recupera informações da variável que é para ser usado como código PHP válido. No exemplo abaixo, essa função é usada em um objeto ‘Lemon’.
class Fruit { public $name = 'Lemon'; } $export = var_export(new Fruit(), true);
Uma vez que um objeto é um tipo complexo não há sintaxe genérica para construí-la junto com seus membros. Em vez disso, var_export cria a seguinte string.
Fruit::__set_state(array( 'name' => 'Lemon', ))
Esta cadeia conta com um método estático __set_state a ser definida para o objeto, a fim de construí-lo. Como visto acima, o método __set_state recebe um array associativo contendo pares de valores-chave de cada uma das propriedades do objeto, incluindo os membros privados e protegidos.
static function __set_state(array $array) { $tmp = new Fruit(); $tmp->name = $array['name']; return $tmp; }
Com este método definido na classe exportados para string ela pode agora ser analisado com a função eval para criar um objeto idêntico.
eval('$MyFruit = ' . $export . ';');
Clonagem
Atribuir um objeto a uma variável só vai criar uma nova referência para o mesmo objeto. Para copiar um objeto, o operador clone pode ser usado();.
class Fruit {} $f1 = new Fruit(); $f2 = $f1; // copy object reference $f3 = clone $f1; // copy object
Quando um objeto é clonado suas propriedades serão copiadas para o novo objeto. No entanto, qualquer filho do objeto que podem conter não será clonado, então eles serão compartilhados entre as cópias. Este é o lugar onde o método __clone entra. Ele será chamado na cópia clonado após a clonagem é feito e pode ser usado para clonar quaisquer objetos filho de Apple.
class Apple { //... } class FruitBasket { public $apple; function __construct() { $apple = new Apple(); } function __clone() { $this->apple = clone $this->apple; } }
Uma resposta