Sobrecarga em PHP provê recursos para "criar" dinamicamente membros e métodos. Estas entidades dinâmicas são processadas via métodos mágicos que podem estabelecer em uma classe para vários tipos de ações.
Os métodos sobrecarregados são invocados quando interagem com membros ou métodos que não foram declarados ou não são visíveis no escopo corrente. O resto desta seção usará os termos "membros inacessíveis" e "métodos inacessíveis" para se referirir a esta combinação de declaração e visibilidade.
Todos os métodos sobrecarregados devem ser definidos como públicos.
Nota: Nenhum dos argumentos destes métodos mágicos podem ser passados por referência.
Nota: A interpretação do PHP de "sobrecarga" é diferente da maioria das linguagens orientadas a objeto. Sobrecarga tradicionalmente provê a habilidade de ter múltiplos métodos com o mesmo nome, mas diferentes quantidades e tipos de argumentos.
Versão | Descrição |
---|---|
5.3.0 | Adicionado __callStatic(). Adicionado warning para reforçar a visibilidade pública e a declaração não estática. |
5.1.0 | Adicionados __isset() e __unset(). |
__set() é executado ao se escrever dados para membros inacessíveis.
__get() é utilizados para ler dados de membros inacessíveis.
__isset() é disparado para chamar isset() ou empty() em membros inacessíveis.
__unset() é invocado quando unset() é usado em membros inacessíveis.
O argumento $name é o nome do membro com o qual se está interagindo. O argumento $value do método __set() especifica o valor para o qual o membro $name deveria ser setado.
Sobrecarga de membros somente trabalha no contexto de objetos. Estes métodos mágicos não serão disparados no contexto estático. Portanto estes métodos não podem ser declarados static.
Exemplo #1 Exemplo de sobrecarga com __get, __set, __isset and __unset
<?php
class MemberTest {
/** Local para dado sobrecarregado. */
private $data = array();
/** Sobrecarga não usada em membros declarados. */
public $declared = 1;
/** Sobrecarga somente utilizada neste quando acessado do lado de fora da
classe. */
private $hidden = 2;
public function __set($name, $value) {
echo "Setando '$name' para '$value'\n";
$this->data[$name] = $value;
}
public function __get($name) {
echo "Obtendo '$name'\n";
if (array_key_exists($name, $this->data)) {
return $this->data[$name];
}
$trace = debug_backtrace();
trigger_error(
'Propriedade não definida via __get(): ' . $name .
' em ' . $trace[0]['file'] .
' na linha ' . $trace[0]['line'],
E_USER_NOTICE);
return null;
}
/** Como em PHP 5.1.0 */
public function __isset($name) {
echo "'$name' está setado?\n";
return isset($this->data[$name]);
}
/** Como em PHP 5.1.0 */
public function __unset($name) {
echo "Unsetting '$name'\n";
unset($this->data[$name]);
}
/** Não é um método mágico, apenas está aqui para exemplo. */
public function getHidden() {
return $this->hidden;
}
}
echo "<pre>\n";
$obj = new MemberTest;
$obj->a = 1;
echo $obj->a . "\n\n";
var_dump(isset($obj->a));
unset($obj->a);
var_dump(isset($obj->a));
echo "\n";
echo $obj->declared . "\n\n";
echo "Vamos experimentar com a proriedade privada chamada 'hidden':\n";
echo "Privados são visíveis dentro da classe, então __get() não usado...\n";
echo $obj->getHidden() . "\n";
echo "Privados não são vidíveis fora da classe, então __get() é usado...\n";
echo $obj->hidden . "\n";
?>
O exemplo acima irá imprimir:
Setando 'a' para '1' Obtendo 'a' 1 'a' está setado? bool(true) Unsetting 'a' 'a' está setado? bool(false) 1 Vamos experimentar com a proriedade privada chamada 'hidden': Privados são visíveis dentro da classe, então __get() não usado... 2 Privados não são visíveis fora da classe, então __get() é usado... Obtendo 'hidden' Notice: Propriedade não definida via __get(): hidden em <file> na linha 70 em <file> na linha 29
__call() é disparado quando invocando métodos inacessíveis em um contexto de objeto.
__callStatic() é disparado quando invocando métodos inacessíveis em um contexto estático.
O argumento $name é o nome do método sendo chamado. O argumento $arguments é um array enumerado contendo os parâmetros passados para o método $name.
Exemplo #2 Sobrecarga de métodos instanciados com __call e __callStatic
<?php
class MethodTest {
public function __call($name, $arguments) {
// Nota: valor de $name é case sensitive.
echo "Chamando método objeto '$name' "
. implode(', ', $arguments). "\n";
}
/** Como em PHP 5.3.0 */
public static function __callStatic($name, $arguments) {
// Nota: valor de $name é case sensitive
echo "Chamando método estático '$name' "
. implode(', ', $arguments). "\n";
}
}
$obj = new MethodTest;
$obj->runTest('no contexto objeto');
MethodTest::runTest('no contexto estático'); // Como em PHP 5.3.0
?>
O exemplo acima irá imprimir:
Chamando método objeto 'runTest' no contexto objeto Chamando método estático 'runTest' no contexto estático