Khai báo và sử dụng hàm tạo __construct trong lớp PHP

Phương thức tạo (Constructors) là phương thức đặc biệt trong lớp (lớp không bắt buộc phải định nghĩa hàm tạo), sự khác biệt của nó với các hàm thông thường ở 3 điểm:

  • Tên của hàm luôn là __construct
  • Bạn không thể gọi hàm một cách tường minh, mà nó luôn được tự động chạy khi đối tượng được tạo ra
  • Nó không thể có câu lệnh return để trả về giá trị hàm

Hàm tạo là nơi thích hợp để khởi tạo các tham số cho lớp, thi hành các tác vụ ban đầu khi đối được tạo ra. Hàm tạo cũng chứa tham số như các hàm thông thường khác.

Ví dụ lớp có hàm tạo

class Book {

    protected $price;
    protected $title;

    // Khai báo lớp có hàm khởi tạo với hai tham số
    function __construct( $title, $price ){
        $this->price = $price;
        $this->title = $title;
    }

    public function getTitle()
    {
        return $this->title;
    }
}

// Toán tử new ten_lop(tham-số-hàm-khởi-tạo) => Tạo đối tượng mới,
// phương thức khởi tạo được thi hành
$vatly = new Book("VAT LY LOP 10",20000);
$toan =  new Book("TOAN 10",30000);

echo $vatly->getTitle();        // VAT LY LOP 10
echo $toan->getTitle();         // TOAN 10

Trong PHP không cho phép khai báo nhiều phương thức khởi tạo!

Khai báo thuộc tính lớp tại tham số hàm tạo

PHP8: Cho phép tạo ra thuộc tính lớp (property) bằng cách khai báo tại tham số hàm khởi tạo, chỉ caaf tham số đó có từ khóa xác định phạm vi truy cập (public, private, protected). Giá trị thuộc tính được gán ngay bằng tham số - khi bạn tạo đối tượng mới

class Book {
    // $title, $price sẽ trở thành thuộc tính của lớp
    function __construct(protected $title, protected $price) {

    }

    public function getTitle()
    {
        return $this->title;
    }
}

$toan =  new Book("TOAN 10",30000);
echo $toan->getTitle();

Khởi tạo đối tượng với hàm factory

Factory Method đây là một pattern lập trình, bạn không tạo ra đối tượng trực tiếp bằng cách gọi hàm khởi tạo - mà tạo thông qua một phương thức khác, đó là phương thức factory. Như vậy factory method là phương thức để tạo đối tượng.

Trong lớp Book trên, chỉ có một phương thức khởi tạo hai tham số (PHP không cho phép có nhiều phương thức khởi tạo), vậy nếu muốn khởi tạo đối tượng từ dữ liệu khác như truyền vào tử mảng, truyền vào từ một json thì sao. Lúc đó bạn có thể tạo ra hàm factory, ví dụ:

// $data mảng có hai phần tử title và price
function bookFromArrayData(array $data) : Book
{
    $book = new Book($data['title'], $data['price']);
    // ... việc khác trên book nếu cần
    return $book;
}

Vậy bạn có thể tạo đối tượng mới bằng cách:

$data = ['title' => 'TOAN', 'price => 3000];

$toan =  new bookFromArrayData($data);

Thường phương thức factory khai báo trực tiếp trong lớp và thiết lập nó là phương thức tĩnh với từ khóa static (để gọi được thông qua tên lớp, không cần tạo đối tượng trước khi gọi). Nếu vậy kiểu từ khóa static sử dụng trong phương thức tương đương tên lớp. Thay vì trả về kiểu :Book bạn có thể viết :static, thay vì new Book(...) bạn có thể viết new static(...)

class Book {

    function __construct(protected $title, protected $price ) { }

    // $data mảng có hai phần tử title và price
    public static function bookFromArrayData(array $data) : static
    {
        $book = new static($data['title'], $data['price']);
        return $book;
    }

    public function getTitle()
    {
        return $this->title;
    }
}

// Tạo đối tượng bằng cách thông thường
$book1 = new Book('Abc', 123);

// Tạo đối tượng bằng hàm factory
$book2 = Book::bookFromArrayData(['title' => 'Xyz', 321]);

Có thể tạo nhiều factory để đáp ứng các cách tạo đối tượng khác nhau.

Hàm hủy __destruct trong lớp PHP

Trong lớp nếu có hàm với tên __destruct() - không tham số/không trả về dữ liệu. Thì phương thức này (hàm) tự động thi hành khi đối tượng bị hủy (đối tượng không còn biến nào tham chiều), hoặc bạn có thể gọi phương thức unset() để hủy (giải phóng) một đối tượng, thì lúc này hàm hủy tự chạy.

class Book {

    function __construct(protected $title, protected $price ) { }
    public function __destruct()
    {
        echo 'Đối tượng bị hủy';
    }

    public function getTitle()
    {
        return $this->title;
    }
}

$b = new Book('A', 123);
// Hủy $b nên hàm hủy sẽ chạy
unset($b);

Đăng ký nhận bài viết mới