__get, __set, __isset, __unset
Thuộc phần Lập trình hướng đối tượng trong hành trình PHP của Coddy. Bài học 46 trên 91.
PHP cung cấp bốn phương thức ma thuật để chặn thao tác truy cập thuộc tính: __get(), __set(), __isset() và __unset(). Chúng được kích hoạt khi bạn cố truy cập các thuộc tính không tồn tại hoặc không thể truy cập.
Phương thức __get() được gọi khi đọc một thuộc tính không thể truy cập, còn __set() xử lý việc ghi vào thuộc tính đó. Nhờ vậy, bạn có thể tạo thuộc tính động hoặc thêm logic khi truy cập thuộc tính:
<?php
class DynamicObject {
private array $data = [];
public function __get(string $name): mixed {
return $this->data[$name] ?? null;
}
public function __set(string $name, mixed $value): void {
$this->data[$name] = $value;
}
}
$obj = new DynamicObject();
$obj->title = "Hello";
$obj->count = 42;
echo $obj->title . " - " . $obj->count;
Đầu ra:
Hello - 42Phương thức __isset() được gọi khi dùng isset() hoặc empty(), còn __unset() xử lý khi gọi hàm unset():
<?php
class DynamicObject {
private array $data = [];
public function __set(string $name, mixed $value): void {
$this->data[$name] = $value;
}
public function __isset(string $name): bool {
return isset($this->data[$name]);
}
public function __unset(string $name): void {
unset($this->data[$name]);
}
}
$obj = new DynamicObject();
$obj->name = "Test";
echo isset($obj->name) ? "exists" : "missing";
Đầu ra:
existsCác phương thức này thường được dùng để tạo vùng chứa dữ liệu linh hoạt, triển khai tải dữ liệu lười hoặc xây dựng các đối tượng hoạt động như mảng mà vẫn giữ cấu trúc hướng đối tượng.
Thử thách
DễHãy xây dựng một trình quản lý cấu hình linh hoạt, lưu trữ các thiết lập một cách linh động bằng các phương thức ma thuật. Lớp của bạn sẽ chặn thao tác truy cập thuộc tính để quản lý các giá trị cấu hình, kiểm tra thiết lập có tồn tại hay không và xóa chúng khi cần, tất cả mà không cần định nghĩa rõ từng thuộc tính.
Bạn sẽ sắp xếp code trong hai tệp:
Config.php: Tạo lớpConfigdùng một mảng riêng tư để lưu trữ nội bộ các giá trị cấu hình. Cài đặt cả bốn phương thức ma thuật cho thuộc tính:__get($name): Trả về giá trị của khóa đã cho, hoặc"undefined"nếu khóa không tồn tại__set($name, $value): Lưu giá trị dưới khóa đã cho__isset($name): Trả về kết quả cho biết khóa có tồn tại trong cấu hình hay không__unset($name): Xóa khóa khỏi cấu hình
count()để trả về số lượng thiết lập đã lưu.main.php: Nạp tệp Config. Bạn sẽ nhận ba đầu vào: tên một thiết lập, giá trị của thiết lập đó và tên một thiết lập thứ hai. Tạo một instanceConfigvà thực hiện các thao tác sau:- Đặt giá trị đã cho cho thiết lập thứ nhất
- In ra thiết lập thứ nhất có tồn tại hay không bằng
isset(): xuất"exists"hoặc"missing" - In ra giá trị của thiết lập thứ nhất
- In ra số lượng thiết lập hiện tại
- Dùng
unset()để xóa thiết lập thứ nhất - In ra thiết lập thứ nhất hiện có tồn tại hay không: xuất
"exists"hoặc"missing" - In ra giá trị của thiết lập thứ hai (thiết lập này chưa từng được đặt)
Mỗi kết quả đầu ra phải nằm trên một dòng riêng. Các phương thức ma thuật cho phép bạn tương tác với đối tượng Config bằng cú pháp thuộc tính tự nhiên như $config->theme = "dark" và isset($config->theme), dù không có thuộc tính thực nào được định nghĩa.
Tự làm thử
<?php
require_once 'Config.php';
// Đọc dữ liệu đầu vào
$settingName1 = trim(fgets(STDIN));
$settingValue = trim(fgets(STDIN));
$settingName2 = trim(fgets(STDIN));
// TODO: Tạo một instance của Config
// TODO: Gán giá trị đã cho cho thiết lập đầu tiên
// TODO: In ra thiết lập đầu tiên có tồn tại hay không ("exists" hoặc "missing")
// TODO: In ra giá trị của thiết lập đầu tiên
// TODO: In ra số lượng thiết lập hiện tại
// TODO: Dùng unset() để xóa thiết lập đầu tiên
// TODO: In ra thiết lập đầu tiên hiện có tồn tại hay không ("exists" hoặc "missing")
// TODO: In ra giá trị của thiết lập thứ hai (thiết lập này chưa từng được gán giá trị)
?>Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Lập trình hướng đối tượng
1Nền tảng về OOP
Tệp bên ngoàiGiới thiệu về OOPLớp và đối tượngTừ khóa $thisPhương thứcThuộc tínhHàm khởi tạo (__construct)Hàm hủy (__destruct)Ôn tập: máy tính đơn giản4Kế thừa
Kế thừa cơ bảnTừ khóa parent::Ghi đè phương thứcTừ khóa finalLớp trừu tượngÔn tập: hệ thống phân cấp nhân viên7Đóng gói
Công khai, được bảo vệ, riêng tưTìm hiểu sâu về bộ điều chỉnh quyền truy cậpGetter và setterẨn thông tinRút gọn hàm khởi tạo (8.0)Ôn tập: hệ thống hồ sơ học sinh2Không gian tên và tự động nạp
Giới thiệu về không gian tênTừ khóa useChuẩn tự động nạp PSR-4Trình tự động nạp của ComposerÔn tập: dự án có tổ chức5Giao diện và hợp đồng
Giới thiệu về giao diệnTriển khai giao diệnTriển khai nhiều giao diệnGiao diện và lớp trừu tượngGợi ý kiểu với giao diệnÔn tập: Máy tính hình học8Phương thức ma thuật
Giới thiệu về phương thức ma thuật__toString và __debugInfo__get, __set, __isset, __unset__call và __callStatic__clone và sao chép đối tượng__serialize và __unserializeÔn tập: Bộ sưu tập tùy chỉnh3Thuộc tính của lớp
Thuộc tính instance và staticHằng số trong lớpPhương thức và thuộc tính staticThuộc tính private và protectedThuộc tính chỉ đọc (PHP 8.1)Ôn tập: Trình quản lý tài khoản ngân hàng6Đa hình
Xem lại việc ghi đè phương thứcĐa hình qua giao diệnGợi ý kiểu và kiểu hợpLiên kết tĩnh muộnÔn tập: bộ xử lý thanh toánTự luyện tập: Trình biên dịch PHP online