Getter và setter
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 40 trên 91.
Bây giờ bạn đã hiểu về các từ bổ nghĩa quyền truy cập, làm thế nào để tương tác an toàn với các thuộc tính private từ bên ngoài lớp? Câu trả lời là phương thức truy xuất và thiết lập (getters and setters), tức các phương thức public giúp kiểm soát quyền truy cập vào dữ liệu private.
Getter lấy giá trị của một thuộc tính, còn setter thay đổi giá trị đó. Mẫu này cho phép bạn thêm quy tắc xác thực hoặc logic khi truy cập hay thay đổi dữ liệu:
<?php
class User {
private string $email;
private int $age;
public function getEmail(): string {
return $this->email;
}
public function setEmail(string $email): void {
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
$this->email = $email;
}
}
public function getAge(): int {
return $this->age;
}
public function setAge(int $age): void {
if ($age >= 0 && $age <= 150) {
$this->age = $age;
}
}
}
$user = new User();
$user->setEmail("john@example.com");
$user->setAge(25);
echo $user->getEmail() . "\n";
echo $user->getAge();
Đầu ra:
john@example.com
25Phương thức setter kiểm tra định dạng email và đảm bảo tuổi hợp lý trước khi lưu các giá trị. Nếu không có setter, bất kỳ ai cũng có thể gán trực tiếp dữ liệu không hợp lệ. Bạn cũng có thể tạo thuộc tính chỉ đọc bằng cách chỉ cung cấp getter, hoặc thuộc tính chỉ ghi bằng cách chỉ cung cấp setter.
Điểm chính: Getter và setter giúp bạn kiểm soát cách truy cập và chỉnh sửa dữ liệu riêng tư, cho phép kiểm tra tính hợp lệ, định dạng hoặc áp dụng logic tùy chỉnh.
Thử thách
DễHãy xây dựng một hệ thống quản lý hàng tồn kho sản phẩm, sử dụng getter và setter để bảo vệ và xác thực dữ liệu sản phẩm. Bạn sẽ tạo một lớp Product để đảm bảo giá luôn dương và số lượng hàng tồn kho không bao giờ âm, qua đó minh họa cách setter có thể thực thi các quy tắc kinh doanh.
Bạn sẽ sắp xếp code trong hai tệp:
Product.php: Tạo một lớpProductcó ba thuộc tính riêng tư:$name(chuỗi),$price(số thực) và$stock(số nguyên). Tạo getter và setter cho từng thuộc tính với các quy tắc xác thực sau:setName()chỉ nên chấp nhận chuỗi không rỗng. Nếu chuỗi rỗng sau khi xóa khoảng trắng ở đầu và cuối, đừng cập nhật thuộc tínhsetPrice()chỉ nên chấp nhận giá trị lớn hơn 0: từ chối giá bằng 0 hoặc giá âmsetStock()chỉ nên chấp nhận giá trị từ 0 trở lên: từ chối số lượng hàng tồn kho âm
getInfo()trả về"[name]: $[price] ([stock] in stock)", trong đó giá được định dạng với 2 chữ số thập phân.main.php: Đưa tệp Product vào. Bạn sẽ nhận được bốn đầu vào: tên sản phẩm, giá, số lượng hàng tồn kho và giá mới để cập nhật. Tạo một đối tượngProductrồi dùng các setter để gán tên, giá ban đầu (đã chuyển đổi sang số thực) và số lượng hàng tồn kho (đã chuyển đổi sang số nguyên). In kết quả củagetInfo(). Sau đó thử cập nhật giá bằng giá trị giá mới (đã chuyển đổi sang số thực) và in lạigetInfo(). Cuối cùng, thử đặt số lượng hàng tồn kho thành-5(một giá trị không hợp lệ) rồi ingetInfo()thêm một lần nữa để xác nhận số lượng hàng tồn kho không thay đổi.
Các setter của bạn đóng vai trò như người gác cổng. Chúng xác thực dữ liệu đầu vào trước khi cho phép thay đổi các thuộc tính riêng tư. Khi nhận dữ liệu không hợp lệ, chẳng hạn như số lượng hàng tồn kho âm, setter chỉ cần bỏ qua dữ liệu đó và giữ nguyên giá trị hợp lệ hiện có. Đây chính là sức mạnh của tính đóng gói: đối tượng của bạn luôn duy trì tính toàn vẹn bất kể code bên ngoài cố làm gì.
Tự làm thử
<?php
require_once 'Product.php';
// Đọc các giá trị đầu vào
$name = trim(fgets(STDIN));
$price = trim(fgets(STDIN));
$stock = trim(fgets(STDIN));
$newPrice = trim(fgets(STDIN));
// TODO: Tạo một instance Product mới
// TODO: Dùng các phương thức setter để gán tên, giá và stock ban đầu, trong đó giá là số thực và stock là số nguyên
// TODO: In ra kết quả của getInfo()
// TODO: Cập nhật giá bằng newPrice (dưới dạng số thực), rồi in getInfo() lần nữa
// TODO: Thử đặt stock thành -5 (không hợp lệ), rồi in getInfo() để xác nhận stock không thay đổi
?>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