Constructor
__construct
(
mixed ...$values
= ""
) :
void
PHP 5 permite programatorilor să definească constructori pentru clase.
Clasele care au definit un constructor vor apela această metodă la fiecare
obiect nou creat, pentru ca acesta (obiectul) să fie utilizabil pentru
inițializare înante de a fi folosit.
Notă:
Constructorul-părinte nu este apelat implicit dacă clasa-fiică definește
un constructor. Pentru a apela un constructor-părinte, este necesar de a
apela parent::__construct() din cadrul
constructorului-fiu. Dacă clasa-fiică nu definește un constructor, atunci
acesta poate fi moștenit de la clasa-părinte la fel ca o metodă normală a
clasei (dacă aceasta nu a fost declarată ca privată).
Example #1 utilizarea noilor constructori unificați
<?php
class BaseClass {
function __construct() {
print "In BaseClass constructor\n";
}
}
class SubClass extends BaseClass {
function __construct() {
parent::__construct();
print "In SubClass constructor\n";
}
}
class OtherSubClass extends BaseClass {
// inherits BaseClass's constructor
}
// In BaseClass constructor
$obj = new BaseClass();
// In BaseClass constructor
// In SubClass constructor
$obj = new SubClass();
// In BaseClass constructor
$obj = new OtherSubClass();
?>
Spre deosebire de alte metode, PHP nu va genera un mesaj de eroare de nivel
E_STRICT
atunci când __construct()
este suprascrisă cu alți parametri decât cei ai metodei
__construct() din clasa-părinte.
Constructorii sunt metode apelate la inițializarea obiectelor.
Aceștia pot fi definiți cu un număr arbitrar de argumente, care
pot fi opționali sau nu, pot ave tip, și pot avea valoare implicită. Argumentele pentru
constructori se pun între paranteze după numele clasei.
Example #2 Constructori în clasele cu spații de nume
<?php
class Point {
protected int $x;
protected int $y;
public function __construct(int $x, int $y = 0) {
$this->x = $x;
$this->y = $y;
}
}
// Apel cu ambii parametrii
$p1 = new Point(4, 5);
// Apel cu argumentul necesar. $y va prelua valoare implictă 0.
$p2 = new Point(4);
// Cu argumente numite (începând cu PHP 8.0):
$p3 = new Point(y: 5, x: 4);
?>
Dacă o clasă nu are constructor, sau constructorul nu are nici un argument necesar, parantezele
pot fi omise.
Constructorii de stil vechi
Înainte de PHP 8.0.0, clasele din namespaceul global interpretau o metodă cu același nume
ca și clasa ca un constructor de stil vechi. Acea syntaxă este învechită și nerecomandată,
iar utilizarea ei va genera or eroare de tip E_DEPRECATED
dar metoda constructor va fi apelată.
Dacă atât __construct() cât și o motodă cu acelasi nume cu al clasei sunt
definite, numai __construct() va fi apelat.
În clasele din namespace-uri, sau orice altă clasă începând cu PHP 8.0.0, o metodă cu același nume
cu al clasei nu are însemnătate specială.
Folosiți întotdeauna __construct() în cod nou.
Metode de creare statice
PHP suportă un singur constructor într-o clasă. În unele cazuri, însă, este nevoie
să permitem crearea unui obiect în diferite feluri cu intrări diferite.
Metoda recomandată este folosind metode statice care împacheterază constructorul.
Example #4 Folosirea metodelor de creare statice
<?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);
Constructorul poate fi făcut private sau protected pentru a preveni apelarea din exterior.
Dacă se alege această cale, numai o metodă statică va putea instanția classa. Pentru că sunt definite în
aceeași clasă au access la metodele private, chiar dacă obiectele instanțiate sunt
diferite. Un constructor private este opțional și poate fi o alegere bună în funcție
de cerințe...
Cele trei metode statice publice demonstrează feluri diferite de instanțiere a obiectelor.
fromBasicData()
permite exact parametrii necesari, și apoi crează
obiectul apelând constructorul și returnând rezultatul.
fromJson()
acceptă un text în format JSON și îl pre-procesează pentru într-un
format necesar constructorului. Apoi returnează obiectul nou.
fromXml()
acceptă un text XML, în pro-procesează, apoi crează un obiect
gol. Constructorul este apelat, dar pentru că toți parapetrii sunt opționali nu sunt
pasați. Apoi asignează valori corecte proprietăților obiectului înainte de a întoarce rezultatul.
În toate cele trei cazuri, cuvântul cheie static
este tradus în numele clasei în care este scris acest cod.
În acest caz, Product
.
Destructori
__destruct
(
) : void
PHP 5 introduce un concept de distrugere a unui obiect similar cu cel
regăsit în alte limbaje de programare orientate pe obiecte (C++).
Metoda de distrugere va fi apelată imediat ce nu mai sunt careva referințe
către un anumit obiect sau în orice ordine în timpul secvenței de deconectare.
Example #5 Exemplu destructor
<?php
class MyDestructableClass
{
function __construct() {
print "In constructor\n";
}
function __destruct() {
print "Destroying " . __CLASS__ . "\n";
}
}
$obj = new MyDestructableClass();
La fel ca la constructori, destructorii-părinti nu vor fi apelați implicit.
Pentru a apela destructorul-părinte trebuie să apelați explicit
parent::__destruct() în destructorul descendent. De
asemenea, ca și în cazul constructorilor, o clasă-fiică poate să moștenească
destructorul părintelui dacă ea nu-și implementează destructorul propriu.
Destructorul este apelat chiar dacă scriptul este terminat cu apelul la funcția
exit(). Apelând
exit() într-un destructor
va preveni apelarea tuturor rutinelor de terminare din scriptul respectiv.
Notă:
Destructorii apelați la momentul terminării execuției scriptului au
antetele HTTP trimise deja. Directorul de lucru în timpul fazei de
deconectare a scriptului poate să difere în cazul anumitor SAPI-uri
(de ex. Apache).
Notă:
Încercarea de a arunca o excepție dintr-un destructor (apelat la momentul
terminării execuției scriptului) va cauza o eroare fatală.