PHP thực hiện encapsulation , một trong những nguyên tắc quan trọng của OOP với các từ khóa kiểm soát truy cập: public, private và protected .
Đóng gói (Encapsulation) đề cập đến cơ chế giữ các thành viên dữ liệu hoặc thuộc tính của một đối tượng tránh xa tầm với của môi trường bên ngoài lớp, cho phép truy cập có kiểm soát chỉ thông qua các phương thức hoặc hàm có sẵn trong lớp.
Sơ đồ dưới đây minh họa nguyên tắc đóng gói trong phương pháp lập trình hướng đối tượng.
Danh sách từ khóa của PHP chứa các từ khóa sau đây xác định khả năng truy cập của các thuộc tính và phương thức của một đối tượng, mà là một thể hiện của một lớp trong PHP −
Public − Các thành viên của lớp có thể truy cập từ bất kỳ đâu, ngay cả từ bên ngoài phạm vi của lớp, nhưng chỉ với tham chiếu đối tượng.
Private − Các thành viên của lớp có thể được truy cập bên trong chính lớp đó. Điều này ngăn chặn việc truy cập các thành viên từ bên ngoài lớp ngay cả khi có tham chiếu đến thể hiện của lớp.
Protected − Các thành viên chỉ có thể được truy cập trong lớp và lớp con của nó, không ở đâu khác.
Ba từ khóa này " public, private và protected " thường được gọi là các bộ điều chỉnh quyền truy cập. Chúng cũng được gọi là các chế độ hiển thị, vì chúng quyết định mức độ mà một thành viên lớp nhất định có sẵn.
Trong PHP, các thành viên của lớp (cả biến thành viên lẫn hàm thành viên) mặc định là công khai (public).
Trong chương trình sau, các biến thành viên title và price của đối tượng có thể truy cập tự do từ bên ngoài lớp vì chúng là công khai theo mặc định, trừ khi được chỉ định khác.
<?php class Person { /* Member variables */ var $name; var $age; /*Constructor*/ function __construct(string $param1="Ravi", int $param2=28) { $this->name = $param1; $this->age = $param2; } function getName() { echo "Name: $this->name" . PHP_EOL;; } function getAge() { echo "Age: $this->age" . PHP_EOL;; } } $b1 = new Person(); $b1->getName(); $b1->getAge(); echo "Name : $b1->name Age: $b1->age" . PHP_EOL; ?>
Nó sẽ tạo ra output −
Name: Ravi Age: 28 Name : Ravi Age: 28
Note rằng các thuộc tính của tất cả các thành viên trong lớp là công khai theo mặc định, bạn có thể khai báo rõ ràng chúng là công khai nếu muốn. Do đó, các phương thức thể hiện getName() và getAge() có thể được gọi từ bên ngoài lớp.
Vì các thuộc tính name và age cũng là công khai (public), nên chúng cũng có thể được truy cập từ bên ngoài lớp, điều này không mong muốn theo nguyên tắc đóng gói (encapsulation).
Như đã đề cập ở trên, nguyên tắc đóng gói yêu cầu rằng các biến thành viên không nên được truy cập trực tiếp. Chỉ có các phương thức mới có quyền truy cập vào các biến dữ liệu. Do đó, chúng ta cần đặt các biến thành viên thành private và các phương thức thành public.
Hãy thay đổi khai báo các thuộc tính name và age thành private và chạy đoạn mã PHP sau −
<?php class Person { /* Member variables */ private $name; private $age; /*Constructor*/ function __construct(string $param1="Ravi", int $param2=28) { $this->name = $param1; $this->age = $param2; } public function getName() { echo "Name: $this->name" . PHP_EOL;; } public function getAge(){ echo "Age: $this->age" . PHP_EOL;; } } $b1 = new Person(); $b1->getName(); $b1->getAge(); echo "Name : $b1->name Age: $b1->age" . PHP_EOL; ?>
Nó sẽ tạo ra output −
Name: Ravi Age: 28 PHP Fatal error: Uncaught Error: Cannot access private property Person::$name in person.php:27
Thông điệp lỗi cho biết lý do rằng một thuộc tính riêng không thể được truy cập từ phạm vi công khai.
Ảnh hưởng của việc chỉ định quyền truy cập protected cho một thành viên trong lớp có hiệu lực trong trường hợp kế thừa lớp. Chúng ta biết rằng các thành viên public có thể truy cập từ bất kỳ đâu bên ngoài lớp, trong khi các thành viên private thì không thể truy cập từ bất kỳ đâu bên ngoài lớp.
Từ khóa protected cấp quyền truy cập vào một đối tượng của cùng một lớp và một đối tượng của lớp kế thừa của nó, từ chối quyền truy cập từ bất kỳ môi trường nào khác.
Hãy kế thừa lớp person và định nghĩa một lớp student. Chúng ta sẽ thay đổi thuộc tính name từ private thành protected. Lớp student có một phương thức công khai mới là getDetails() để in ra giá trị của các thuộc tính name và age.
Person class
<?php class Person { /* Member variables */ protected $name; private $age; /*Constructor*/ function __construct(string $param1="Ravi", int $param2=28) { $this->name = $param1; $this->age = $param2; } public function getName(){ echo "Name: $this->name" . PHP_EOL;; } public function getAge() { echo "Age: $this->age" . PHP_EOL;; } }
Student class
class student extends Person { public function getDetails() { echo "My Name: $this->name" . PHP_EOL; echo "My age: $this->age" . PHP_EOL; } } $s1 = new student(); $s1->getDetails(); ?>
Nó sẽ tạo ra output −
My Name: Ravi PHP Warning: Undefined property: student::$age in person.php on line 28 My age:
Bảng dưới đây minh họa các quy tắc truy cập của các thành viên lớp trong PHP −