← Lekcje
PHP · lekcja 14

Programowanie obiektowe 2/3: __construct i __destruct

Dzisiaj:

  1. Konstruktor __construct(): metoda, która uruchamia się sama przy każdym new
  2. Destruktor __destruct(): metoda, która uruchamia się sama, gdy obiekt znika
  3. Obiekt tworzony jedną linią, z wartościami od razu w środku
  4. Ćwiczenie: dopisujemy konstruktor do class-product.php z lekcji poprzedniej
Rozgrzewka · 3 minuty

Rozgrzewka: klasa i obiekt

  1. Czym różni się klasa od obiektu?
  2. Do czego służy słowo kluczowe new?
  3. Co oznacza $this wewnątrz metody klasy?
Część 1 · Konstruktor i destruktor

Życie obiektu: od new do końca

Konstruktor to metoda o specjalnej nazwie __construct(). PHP wywołuje ją samo, za każdym razem, gdy powstaje nowy obiekt przez new. Nie trzeba jej wywoływać ręcznie. Destruktor to metoda __destruct(): PHP wywołuje ją samo, gdy obiekt przestaje być potrzebny.

new Product() __construct() wywołane automatycznie życie obiektu metody, właściwości __destruct() gdy obiekt znika
PHP Manual: „Classes which have a constructor method call this method on each newly-created object [...] The destructor method will be called as soon as there are no other references to a particular object” · php.net/manual/en/language.oop5.decon.php
Część 2 · Bez konstruktora, z konstruktorem

Dwa sposoby: ręcznie i automatycznie

bez konstruktora: 3 kroki new Product() $product1->name = "Keyboard"; $product1->price = 120; z konstruktorem: 1 krok new Product("Keyboard", 120)

Bez konstruktora (lekcja poprzednia)

class Product { public $name; public $price; }

$product1 = new Product();
$product1->name = "Keyboard";
$product1->price = 120;

Z konstruktorem (dzisiaj)

public function __construct($name, $price) {
    $this->name = $name;
    $this->price = $price;
}

$product1 = new Product("Keyboard", 120);
PHP Manual: „If a class has no constructor, or the constructor has no required arguments, the parentheses may be omitted” · php.net/manual/en/language.oop5.decon.php
Część 3 · Konstruktor z parametrami

__construct: parametry jak w zwykłej funkcji

new Product("Keyboard", 120) __construct($name, $price) $this->name = $name; $this->price = $price; $product1 name = "Keyboard" price = 120
$product1 = new Product("Keyboard", 120);
$product2 = new Product("Mouse", 45);

echo $product1->name . " - " . $product1->price;
// Keyboard - 120
PHP Manual: „Constructor arguments are called by placing the arguments in parentheses after the class name” · php.net/manual/en/language.oop5.decon.php
Część 4 · Destruktor

__destruct: gdy obiekt znika

class Product {
    public $name;

    public function __construct($name) {
        $this->name = $name;
        echo "Utworzono: " . $this->name;
    }

    public function __destruct() {
        echo "Usunieto: " . $this->name;
    }
}

$product1 = new Product("Keyboard");
unset($product1);
// Utworzono: Keyboard
// Usunieto: Keyboard

unset() usuwa zmienną. Jeśli to był ostatni dostęp do obiektu, PHP od razu wywołuje __destruct(). Destruktor nie jest obowiązkowy: większość klas na tej lekcji go nie potrzebuje, częściej używa się go do sprzątania (np. zamknięcia pliku).

Ciekawostka z PHP Manual: gdy skrypt się kończy, PHP i tak wywoła destruktor, nawet jeśli zatrzymasz działanie funkcją exit() w środku kodu. Samo wywołanie exit() wewnątrz destruktora zatrzyma jednak resztę sprzątania po skrypcie.

PHP Manual: język.oop5.decon.php, sekcja destruktory · php.net/manual/en/language.oop5.decon.php · ciekawostka: PHP Manual, „The destructor will be called even if script execution is stopped using exit(). Calling exit() in a destructor will prevent the remaining shutdown routines from executing.” · php.net/manual/en/language.oop5.decon.php
Egzamin INF.03

Tak pytają na egzaminie

1. Co będzie wynikiem po wywołaniu przedstawionego skryptu?

class Fruit {
  function __construct() {
    echo "test1";
  }
  function __destruct() {
    echo "test2";
  }
}
$pear = new Fruit();
  1. Nie wyświetli się żaden napis.
  2. Wyświetli się tylko napis „test1”.
  3. Wyświetli się tylko napis „test2”.
  4. Wyświetlą się oba napisy: „test1” i „test2”.

2. W klasie Product konstruktor ma nagłówek __construct($name, $price = 0). Które wywołanie jest poprawne?

  1. new Product();
  2. new Product("Mouse");
  3. new Product;
  4. Product("Mouse", 45);

Poprawnych odpowiedzi może być więcej niż jedna.

CKE, EE.09, styczeń 2022, zadanie 5
Ćwiczenie przy komputerze · 20 minut

Ćwiczenie: konstruktor w class-product.php

  1. Otwórz class-product.php z folderu swojego serwera (htdocs, z lekcji poprzedniej).
  2. W class Product dopisz metodę public function __construct($name, $price), w środku $this->name = $name; i $this->price = $price;.
  3. Usuń stare linie ręcznego ustawiania właściwości i utwórz oba obiekty jedną linią: new Product("Keyboard", 120) i new Product("Mouse", 45).
  4. Wypisz echo nazwę i cenę obu obiektów, każdy w osobnej linii.
  5. Sprawdź w przeglądarce pod localhost/class-product.php.

Ma się pojawić: dwie linie z nazwą i ceną, po jednej na obiekt, dokładnie jak na poprzedniej lekcji, tylko kod jest krótszy.

Zasady pracowni
Na koniec

Sprawdź się

  1. Kiedy PHP wywołuje __construct()?
  2. Czy konstruktor jest obowiązkowy w każdej klasie?
  3. Kiedy PHP wywołuje __destruct()?

To była druga lekcja tematu programowania obiektowego. Na następnej: public i private.

Poza szkołą

A jak to wygląda w produkcji?

Na lekcjiW produkcjiStatus
Konstruktor ustawia dwie właściwości przekazane wprostW większych klasach konstruktor często sprawdza dane wejściowe (np. czy cena nie jest ujemna) zanim je zapisze. To temat kolejnych lekcji (walidacja).nadal w użyciu
Destruktor na lekcji tylko wypisuje tekst (do nauki)W realnym kodzie destruktor rzadko jest potrzebny: PHP samo sprząta pamięć po zakończeniu skryptu; używa się go głównie do zamykania plików lub połączeń, które trzeba zwolnić ręcznie.rzadko używane
Konstruktor przyjmuje parametry w ustalonej kolejności ($name, $price)Od PHP 8.0 można wywołać konstruktor z argumentami nazwanymi (new Product(price: 120, name: "Keyboard")). Kolejność przestaje mieć znaczenie.nadal w użyciu (obie formy)
PHP Manual: „With named parameters (as of PHP 8.0)” · php.net/manual/en/language.oop5.decon.php