La sobrecarga en PHP ofrece los medios para crear
dinámicamente propiedades y métodos. Estas entidades dinámicas se
procesan por los métodos mágicos que se pueden establecer en una clase
para diversas acciones.
Se invoca a los métodos de sobrecarga cuando se interactúa
con propiedades o métodos que no se han declarado o que no son
visibles en el
ámbito activo. A lo largo de esta sección usaremos los términos
propiedades inaccesibles
y métodos
inaccesibles
para referirnos a esta combinación de declaración
y visibilidad.
Todos los métodos sobrecargados deben definirse como public.
Nota:
No se puede pasar ninguno de los parámetros de estos métodos mágicos por referencia.
Nota:
La interpretación de PHP de
overloadinges distinta de la mayoría de los lenguajes orientados a objetos. La sobrecarga tradicionalmente ofrece la capacidad de tener múltiples métodos con el mismo nombre, pero con un tipo o un número distinto de parámetros.
Versión | Descripción |
---|---|
5.3.0 | Se añadió __callStatic. Se añadieron advertencias para hacer cumplir la visibilidad pública e impedir la declaración static. |
5.1.0 | Se añadieron __isset() y __unset(). Se añadió el soporte para __get() para la sobrecarga de propiedades privadas. |
5.0.0 | Se añadió __get(). |
$name
) : bool$name
) : void__set() se ejecuta al escribir datos sobre propiedades inaccesibles (protegidas o privadas) o inexistentes.
__get() se utiliza para consultar datos a partir de propiedades inaccesibles (protegidas o privadas) o inexistentes.
__isset() se lanza al llamar a isset() o a empty() sobre propiedades inaccesibles (protegidas o privadas) o inexistentes.
__unset() se invoca cuando se usa unset() sobre propiedades inaccesibles (protegidas o privadas) o inexistentes.
El parámetro $name es el nombre de la propiedad con la que se está interactuando. En el método __set() el parámetro $value especifica el valor que se debe asignar a la propiedad $name.
La sobrecarga de propiedades sólo funciona en contextos de objetos. Estos métodos mágicos no se lanzarán en contextos estáticos. Por esa razón, no se deben declarar como estáticos. Desde PHP 5.3.0, se emite un aviso si alguno de los métodos de sobrecarga es declarado como static.
Nota:
Debido a la forma en que PHP procesa el operador de asignación, el valor que devuelve __set() se ignora. Del mismo modo, nunca se llama a __get() al encadenar asignaciones como esta:
$a = $obj->b = 8;
Ejemplo #1 Sobrecarga de propiedades mediante los métodos __get(), __set(), __isset() y __unset()
<?php
class PropertyTest
{
/** Localización de los datos sobrecargados. */
private $data = array();
/** La sobrecarga no se usa en propiedades declaradas. */
public $declared = 1;
/** La sobre carga sólo funciona aquí al acceder desde fuera de la clase. */
private $hidden = 2;
public function __set($name, $value)
{
echo "Estableciendo '$name' a '$value'\n";
$this->data[$name] = $value;
}
public function __get($name)
{
echo "Consultando '$name'\n";
if (array_key_exists($name, $this->data)) {
return $this->data[$name];
}
$trace = debug_backtrace();
trigger_error(
'Propiedad indefinida mediante __get(): ' . $name .
' en ' . $trace[0]['file'] .
' en la línea ' . $trace[0]['line'],
E_USER_NOTICE);
return null;
}
/** Desde PHP 5.1.0 */
public function __isset($name)
{
echo "¿Está definido '$name'?\n";
return isset($this->data[$name]);
}
/** Desde PHP 5.1.0 */
public function __unset($name)
{
echo "Eliminando '$name'\n";
unset($this->data[$name]);
}
/** No es un método mágico, esta aquí para completar el ejemplo. */
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 "Vamos a probar con la propiedad privada que se llama 'hidden':\n";
echo "Las propiedades privadas pueden consultarse en la clase, por lo que no se usa __get()...\n";
echo $obj->getHidden() . "\n";
echo "Las propiedades privadas no son visibles fuera de la clase, por lo que se usa __get()...\n";
echo $obj->hidden . "\n";
?>
El resultado del ejemplo sería:
Estableciendo 'a' a '1' Consultando 'a' 1 ¿Está definido 'a'? bool(true) Eliminando 'a' ¿Está definido 'a'? bool(false) 1 Vamos a probar con la propiedad privada que se llama 'hidden': Las propiedades privadas pueden consultarse en la clase, por lo que no se usa __get()... 2 Las propiedades privadas no son visibles fuera de la clase, por lo que se usa __get()... Consultando 'hidden' Notice: Propiedad indefinida mediante __get(): hidden en <file> en la línea 69 in <file>en la línea 28
__call() es lanzado al invocar un método inaccesible en un contexto de objeto.
__callStatic() es lanzado al invocar un método inaccesible en un contexto estático.
El parámetro $name corresponde al nombre del método al que se está llamando. El parámetro $arguments es un array enumerado que contiene los parámetros que se han pasado al método $name.
Ejemplo #2 Sobrecarga de métodos mediante los métodos __call() and __callStatic()
<?php
class MethodTest
{
public function __call($name, $arguments)
{
// Nota: el valor $name es sensible a mayúsculas.
echo "Llamando al método de objeto '$name' "
. implode(', ', $arguments). "\n";
}
/** Desde PHP 5.3.0 */
public static function __callStatic($name, $arguments)
{
// Nota: el valor $name es sensible a mayúsculas.
echo "Llamando al método estático '$name' "
. implode(', ', $arguments). "\n";
}
}
$obj = new MethodTest;
$obj->runTest('en contexto de objeto');
MethodTest::runTest('en contexto estático'); // Desde PHP 5.3.0
?>
El resultado del ejemplo sería:
Llamando al método de objeto 'runTest' en contexto de objeto Llamando al método estático 'runTest' en contexto estático