PHP
Metodos magicos
Buscar..
__get (), __set (), __isset () y __unset ()
Siempre que intentes recuperar un campo determinado de una clase como esta:
$animal = new Animal();
$height = $animal->height;
PHP invoca el método mágico __get($name)
, con $name
igual a "height"
en este caso. Escribiendo en un campo de clase como tal:
$animal->height = 10;
__set($name, $value)
método mágico __set($name, $value)
, con $name
igual a "height"
y $value
igual a 10
.
PHP también tiene dos funciones isset()
, que comprueba si existe una variable, y unset()
, que destruye una variable. Verificando si un campo de objetos está configurado así:
isset($animal->height);
__isset($name)
la función __isset($name)
en ese objeto. Destruyendo una variable así:
unset($animal->height);
__unset($name)
la función __unset($name)
en ese objeto.
Normalmente, cuando no define estos métodos en su clase, PHP simplemente recupera el campo tal como está almacenado en su clase. Sin embargo, puede anular estos métodos para crear clases que puedan contener datos como una matriz, pero que se puedan usar como un objeto:
class Example {
private $data = [];
public function __set($name, $value) {
$this->data[$name] = $value;
}
public function __get($name) {
if (!array_key_exists($name, $this->data)) {
return null;
}
return $this->data[$name];
}
public function __isset($name) {
return isset($this->data[$name]);
}
public function __unset($name) {
unset($this->data[$name]);
}
}
$example = new Example();
// Stores 'a' in the $data array with value 15
$example->a = 15;
// Retrieves array key 'a' from the $data array
echo $example->a; // prints 15
// Attempt to retrieve non-existent key from the array returns null
echo $example->b; // prints nothing
// If __isset('a') returns true, then call __unset('a')
if (isset($example->a)) {
unset($example->a));
}
Función vacía () y métodos mágicos.
Tenga en cuenta que llamar a empty()
en un atributo de clase invocará a __isset()
porque, como se indica en el manual de PHP:
empty () es esencialmente el equivalente conciso de ! isset ($ var) || $ var == falso
__construir () y __destruct ()
__construct()
es el método mágico más común en PHP, porque se usa para configurar una clase cuando se inicializa. El opuesto del método __construct()
es el método __destruct()
. Se llama a este método cuando no hay más referencias a un objeto que creó o cuando fuerza su eliminación. La recolección de basura de PHP limpiará el objeto llamando primero a su destructor y luego eliminándolo de la memoria.
class Shape {
public function __construct() {
echo "Shape created!\n";
}
}
class Rectangle extends Shape {
public $width;
public $height;
public function __construct($width, $height) {
parent::__construct();
$this->width = $width;
$this->height = $height;
echo "Created {$this->width}x{$this->height} Rectangle\n";
}
public function __destruct() {
echo "Destroying {$this->width}x{$this->height} Rectangle\n";
}
}
function createRectangle() {
// Instantiating an object will call the constructor with the specified arguments
$rectangle = new Rectangle(20, 50);
// 'Shape Created' will be printed
// 'Created 20x50 Rectangle' will be printed
}
createRectangle();
// 'Destroying 20x50 Rectangle' will be printed, because
// the `$rectangle` object was local to the createRectangle function, so
// When the function scope is exited, the object is destroyed and its
// destructor is called.
// The destructor of an object is also called when unset is used:
unset(new Rectangle(20, 50));
__Encadenar()
Cuando un objeto se trata como una cadena, se llama al método __toString()
. Este método debe devolver una representación de cadena de la clase.
class User {
public $first_name;
public $last_name;
public $age;
public function __toString() {
return "{$this->first_name} {$this->last_name} ($this->age)";
}
}
$user = new User();
$user->first_name = "Chuck";
$user->last_name = "Norris";
$user->age = 76;
// Anytime the $user object is used in a string context, __toString() is called
echo $user; // prints 'Chuck Norris (76)'
// String value becomes: 'Selected user: Chuck Norris (76)'
$selected_user_string = sprintf("Selected user: %s", $user);
// Casting to string also calls __toString()
$user_as_string = (string) $user;
__invocar()
Este método mágico se llama cuando el usuario intenta invocar el objeto como una función. Los posibles casos de uso pueden incluir algunos enfoques como la programación funcional o algunas devoluciones de llamada.
class Invokable
{
/**
* This method will be called if object will be executed like a function:
*
* $invokable();
*
* Args will be passed as in regular method call.
*/
public function __invoke($arg, $arg, ...)
{
print_r(func_get_args());
}
}
// Example:
$invokable = new Invokable();
$invokable([1, 2, 3]);
// optputs:
Array
(
[0] => 1
[1] => 2
[2] => 3
)
__call () y __callStatic ()
__call()
y __callStatic()
cuando alguien llama a un método de objeto inexistente en un contexto de objeto o estático.
class Foo
{
/**
* This method will be called when somebody will try to invoke a method in object
* context, which does not exist, like:
*
* $foo->method($arg, $arg1);
*
* First argument will contain the method name(in example above it will be "method"),
* and the second will contain the values of $arg and $arg1 as an array.
*/
public function __call($method, $arguments)
{
// do something with that information here, like overloading
// or something generic.
// For sake of example let's say we're making a generic class,
// that holds some data and allows user to get/set/has via
// getter/setter methods. Also let's assume that there is some
// CaseHelper which helps to convert camelCase into snake_case.
// Also this method is simplified, so it does not check if there
// is a valid name or
$snakeName = CaseHelper::camelToSnake($method);
// Get get/set/has prefix
$subMethod = substr($snakeName, 0, 3);
// Drop method name.
$propertyName = substr($snakeName, 4);
switch ($subMethod) {
case "get":
return $this->data[$propertyName];
case "set":
$this->data[$propertyName] = $arguments[0];
break;
case "has":
return isset($this->data[$propertyName]);
default:
throw new BadMethodCallException("Undefined method $method");
}
}
/**
* __callStatic will be called from static content, that is, when calling a nonexistent
* static method:
*
* Foo::buildSomethingCool($arg);
*
* First argument will contain the method name(in example above it will be "buildSomethingCool"),
* and the second will contain the value $arg in an array.
*
* Note that signature of this method is different(requires static keyword). This method was not
* available prior PHP 5.3
*/
public static function __callStatic($method, $arguments)
{
// This method can be used when you need something like generic factory
// or something else(to be honest use case for this is not so clear to me).
print_r(func_get_args());
}
}
Ejemplo:
$instance = new Foo();
$instance->setSomeState("foo");
var_dump($instance->hasSomeState()); // bool(true)
var_dump($instance->getSomeState()); // string "foo"
Foo::exampleStaticCall("test");
// outputs:
Array
(
[0] => exampleCallStatic
[1] => test
)
__sleep () y __wakeup ()
__sleep
y __wakeup
son métodos relacionados con el proceso de serialización. serialize
función serialize
comprueba si una clase tiene un método __sleep
. Si es así, se ejecutará antes de cualquier serialización. Se supone que __sleep
devuelve una matriz de los nombres de todas las variables de un objeto que debe ser serializado.
__wakeup
a su vez se ejecutará con unserialize
si está presente en la clase. Su intención es restablecer los recursos y otras cosas que se necesitan inicializar en la deserialización.
class Sleepy {
public $tableName;
public $tableFields;
public $dbConnection;
/**
* This magic method will be invoked by serialize function.
* Note that $dbConnection is excluded.
*/
public function __sleep()
{
// Only $this->tableName and $this->tableFields will be serialized.
return ['tableName', 'tableFields'];
}
/**
* This magic method will be called by unserialize function.
*
* For sake of example, lets assume that $this->c, which was not serialized,
* is some kind of a database connection. So on wake up it will get reconnected.
*/
public function __wakeup()
{
// Connect to some default database and store handler/wrapper returned into
// $this->dbConnection
$this->dbConnection = DB::connect();
}
}
__información de depuración()
var_dump()
este método al volcar un objeto para obtener las propiedades que deben mostrarse. Si el método no está definido en un objeto, se mostrarán todas las propiedades públicas, protegidas y privadas. - Manual de PHP
class DeepThought {
public function __debugInfo() {
return [42];
}
}
var_dump(new DeepThought());
El ejemplo anterior dará como resultado:
class DeepThought#1 (0) {
}
var_dump(new DeepThought());
El ejemplo anterior dará como resultado:
class DeepThought#1 (1) {
public ${0} =>
int(42)
}
__clon()
__clone
se invoca mediante el uso de la palabra clave clone
. Se utiliza para manipular el estado del objeto tras la clonación, después de que el objeto se haya clonado realmente.
class CloneableUser
{
public $name;
public $lastName;
/**
* This method will be invoked by a clone operator and will prepend "Copy " to the
* name and lastName properties.
*/
public function __clone()
{
$this->name = "Copy " . $this->name;
$this->lastName = "Copy " . $this->lastName;
}
}
Ejemplo:
$user1 = new CloneableUser();
$user1->name = "John";
$user1->lastName = "Doe";
$user2 = clone $user1; // triggers the __clone magic method
echo $user2->name; // Copy John
echo $user2->lastName; // Copy Doe