Constructor
PHP permite a los desarrolladores declarar métodos constructores para las
clases. Aquellas que tengan un método constructor lo invocarán en cada nuevo
objeto creado, lo que lo hace idóneo para cualquier inicialización que
el objeto pueda necesitar antes de ser usado.
Nota:
Los constructores padres no son llamados implícitamente si la clase hija define
un constructor. Para ejecutar un constructor padre, se requiere invocar a
parent::__construct() desde el constructor hijo.
Si el hijo no define un constructor, entonces se puede heredar de la clase
madre como un método de clase normal (si no fue declarada como
privada).
Ejemplo #1 Utilización de nuevos constructores unificados
<?php
class BaseClass {
function __construct() {
print "En el constructor BaseClass\n";
}
}
class SubClass extends BaseClass {
function __construct() {
parent::__construct();
print "En el constructor SubClass\n";
}
}
class OtherSubClass extends BaseClass {
// heredando el constructor BaseClass
}
// En el constructor BaseClass
$obj = new BaseClass();
// En el constructor BaseClass
// En el constructor SubClass
$obj = new SubClass();
// En el constructor BaseClass
$obj = new OtherSubClass();
?>
A diferencia de otros métodos, __construct()
is exempt from the usual
signature compatibility rules
when being extended.
Constructors are ordinary methods which are called during the instantiation of their
corresponding object. As such, they may define an arbitrary number of arguments, which
may be required, may have a type, and may have a default value. Constructor arguments
are called by placing the arguments in parentheses after the class name.
Ejemplo #2 Using constructor arguments
<?php
class Point {
protected int $x;
protected int $y;
public function __construct(int $x, int $y = 0) {
$this->x = $x;
$this->y = $y;
}
}
// Pass both parameters.
$p1 = new Point(4, 5);
// Pass only the required parameter. $y will take its default value of 0.
$p2 = new Point(4);
// With named parameters (as of PHP 8.0):
$p3 = new Point(y: 5, x: 4);
?>
If a class has no constructor, or the constructor has no required arguments, the parentheses
may be omitted.
Old-style constructors
Prior to PHP 8.0.0, classes in the global namespace will interpret a method named
the same as the class as an old-style constructor. That syntax is deprecated,
and will result in an E_DEPRECATED
error but still call that function as a constructor.
If both __construct() and a same-name method are
defined, __construct() will be called.
In namespaced classes, or any class as of PHP 8.0.0, a method named
the same as the class never has any special meaning.
Always use __construct() in new code.
Static creation methods
PHP only supports a single constructor per class. In some cases, however, it may be
desirable to allow an object to be constructed in different ways with different inputs.
The recommended way to do so is by using static methods as constructor wrappers.
Ejemplo #4 Using static creation methods
<?php
class Product {
private ?int $id;
private ?string $name;
private function __construct(?int $id = null, ?string $name = null) {
$this->id = $id;
$this->name = $name;
}
public static function fromBasicData(int $id, string $name): static {
$new = new static($id, $name);
return $new;
}
public static function fromJson(string $json): static {
$data = json_decode($json);
return new static($data['id'], $data['name']);
}
public static function fromXml(string $xml): static {
// Put your own logic here.
$data = convert_xml_to_array($xml);
$new = new static();
$new->id = $data['id'];
$new->name = $data['name'];
return $new;
}
}
$p1 = Product::fromBasicData(5, 'Widget');
$p2 = Product::fromJson($some_json_string);
$p3 = Product::fromXml($some_xml_string);
The constructor may be made private or protected to prevent it from being called externally.
If so, only a static method will be able to instantiate the class. Because they are in the
same class definition they have access to private methods, even if not of the same object
instance. The private constructor is optional and may or may not make sense depending on
the use case.
The three public static methods then demonstrate different ways of instantiating the object.
fromBasicData()
takes the exact parameters that are needed, then creates the
object by calling the constructor and returning the result.
fromJson()
accepts a JSON string and does some pre-processing on it itself
to convert it into the format desired by the constructor. It then returns the new object.
fromXml()
accepts an XML string, preprocesses it, and then creates a bare
object. The constructor is still called, but as all of the parameters are optional the method
skips them. It then assigns values to the object properties directly before returning the result.
In all three cases, the static
keyword is translated into the name of the class the code is in.
In this case, Product
.
Destructor
PHP posee un concepto de destructor similar al de otros
lenguajes orientados a objetos, tal como C++. El método destructor
será llamado tan pronto como no hayan otras referencias a un objeto
determinado, o en cualquier otra circunstancia de finalización.
Ejemplo #5 Ejemplo de Destructor
<?php
class MyDestructableClass
{
function __construct() {
print "En el constructor\n";
}
function __destruct() {
print "Destruyendo " . __CLASS__ . "\n";
}
}
$obj = new MyDestructableClass();
Como los constructores, los destructores padre no serán llamados
implícitamente por el motor. Para ejecutar un destructor padre, se
deberá llamar explícitamente a parent::__destruct()
en el interior del destructor. También como los constructores, una clase child
puede heredar el destructor de los padres si no implementa uno propio.
El destructor será invocado aún si la ejecución del script es detenida
usando exit(). Llamar a exit() en un
destructor evitará que se ejecuten las rutinas restantes de finalización.
Nota:
Los destructores invocados durante la finalización del script tienen
los headers HTTP ya enviados. El directorio de trabajo en la fase de
finalización del script puede ser diferente con algunos SAPIs (por ej., Apache).
Nota:
Intentar lanzar una excepción desde un destructor (invocado en la finalización
del script) causa un error fatal.