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(). |
$name
)$name
)__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. A partir do PHP 5.3.0, um warning é emitido se algum método mágico sobrecarregado é declarado como static.
Nota:
O valor de retorno de __set() é ignorado por causa da forma que o PHP processa o operador de assimilação. Da mesma forma, __get() nunca é chamado quando encadeando assimilações como essa:
$a = $obj->b = 8;
Nota:
Não é possível utilizar propriedades sobrecarregadas em outros constructos de linguagem além de isset(). Isto significa que se empty() é chamado em uma propriedade sobrecarregada, o método sobrecarregado não é chamado.
Para contornar essa limitação, a propriedade sobrecarregada precisa ser copiada em uma variável local dentro do escopo e então ser manipulada por empty().
Exemplo #1 Sobrecarregando propriedades via __get(), __set(), __isset() and __unset()
<?php
class PropertyTest
{
/** Location for overloaded data. */
private $data = array();
/** Overloading not used on declared properties. */
public $declared = 1;
/** Overloading only used on this when accessed outside the class. */
private $hidden = 2;
public function __set($name, $value)
{
echo "Setting '$name' to '$value'\n";
$this->data[$name] = $value;
}
public function __get($name)
{
echo "Getting '$name'\n";
if (array_key_exists($name, $this->data)) {
return $this->data[$name];
}
$trace = debug_backtrace();
trigger_error(
'Undefined property via __get(): ' . $name .
' in ' . $trace[0]['file'] .
' on line ' . $trace[0]['line'],
E_USER_NOTICE);
return null;
}
/** As of PHP 5.1.0 */
public function __isset($name)
{
echo "Is '$name' set?\n";
return isset($this->data[$name]);
}
/** As of PHP 5.1.0 */
public function __unset($name)
{
echo "Unsetting '$name'\n";
unset($this->data[$name]);
}
/** Not a magic method, just here for example. */
public function getHidden()
{
return $this->hidden;
}
}
echo "<pre>\n";
$obj = new PropertyTest;
$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 "Let's experiment with the private property named 'hidden':\n";
echo "Privates are visible inside the class, so __get() not used...\n";
echo $obj->getHidden() . "\n";
echo "Privates not visible outside of class, so __get() is used...\n";
echo $obj->hidden . "\n";
?>
O exemplo acima irá imprimir:
Setting 'a' to '1' Getting 'a' 1 Is 'a' set? bool(true) Unsetting 'a' Is 'a' set? bool(false) 1 Let's experiment with the private property named 'hidden': Privates are visible inside the class, so __get() not used... 2 Privates not visible outside of class, so __get() is used... Getting 'hidden' Notice: Undefined property via __get(): hidden in <file> on line 70 in <file> on line 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)
{
// Note: value of $name is case sensitive.
echo "Calling object method '$name' "
. implode(', ', $arguments). "\n";
}
/** As of PHP 5.3.0 */
public static function __callStatic($name, $arguments)
{
// Note: value of $name is case sensitive.
echo "Calling static method '$name' "
. implode(', ', $arguments). "\n";
}
}
$obj = new MethodTest;
$obj->runTest('in object context');
MethodTest::runTest('in static context'); // As of PHP 5.3.0
?>
O exemplo acima irá imprimir:
Calling object method 'runTest' in object context Calling static method 'runTest' in static context