Kiểu liệt kê (PHP 8.1)
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 59 trên 91.
Trước PHP 8.1, để biểu diễn một tập hợp giá trị cố định như trạng thái hoặc loại, bạn phải dùng hằng số của lớp hoặc chuỗi ma thuật, cả hai cách đều dễ gây lỗi. Enum (kiểu liệt kê) cung cấp một cách phù hợp để định nghĩa kiểu dữ liệu chỉ có thể chứa các giá trị cụ thể đã xác định trước.
Định nghĩa một enum bằng từ khóa enum:
<?php
enum Status {
case Pending;
case Active;
case Completed;
}
$status = Status::Active;
echo $status->name;
Đầu ra:
ActiveEnum cũng có thể có giá trị nền, tức là giá trị chuỗi hoặc số nguyên gắn với từng trường hợp. Điều này hữu ích khi lưu enum trong cơ sở dữ liệu hoặc API:
<?php
enum Status: string {
case Pending = 'pending';
case Active = 'active';
case Completed = 'completed';
}
$status = Status::Active;
echo $status->value;
Đầu ra:
activeEnum có giá trị nền hỗ trợ phương thức from() để tạo enum từ giá trị của nó, và tryFrom() trả về null thay vì ném lỗi khi gặp giá trị không hợp lệ:
<?php
$status = Status::from('active'); // Trả về Status::Active
$invalid = Status::tryFrom('unknown'); // Trả về null
Enum cũng có thể chứa phương thức, giúp chúng hữu ích trong việc đóng gói logic liên quan. Chúng hoạt động liền mạch với gợi ý kiểu dữ liệu, đảm bảo các hàm của bạn chỉ nhận giá trị hợp lệ, không cần kiểm tra xem một chuỗi có khớp với các lựa chọn mong đợi hay không.
Thử thách
DễHãy xây dựng một hệ thống quản lý đơn hàng sử dụng enum để biểu diễn trạng thái đơn hàng một cách an toàn về kiểu dữ liệu. Thay vì dựa vào các chuỗi có thể bị viết sai hoặc không hợp lệ, bạn sẽ tạo một enum có giá trị nền ánh xạ mỗi trạng thái sang một giá trị phù hợp với cơ sở dữ liệu.
Bạn sẽ sắp xếp code trong ba tệp:
OrderStatus.php: Tạo một enum có giá trị nền kiểu chuỗi tên làOrderStatus, gồm bốn trường hợp:Pendingcó giá trị nền là'pending'Processingcó giá trị nền là'processing'Shippedcó giá trị nền là'shipped'Deliveredcó giá trị nền là'delivered'
label()trả về phần mô tả dễ hiểu cho từng trạng thái:Pendingtrả về"Awaiting confirmation"Processingtrả về"Being prepared"Shippedtrả về"On the way"Deliveredtrả về"Order complete"
Order.php: Tạo lớpOrdersử dụng enum. Nạp tệp OrderStatus. Lớp này cần:- Nhận mã đơn hàng (chuỗi) và một
OrderStatustrong hàm khởi tạo bằng cách dùng tính năng thăng cấp hàm khởi tạo - Có phương thức
getInfo()trả về"Order [id]: [status label]" - Có phương thức
getStatusValue()trả về giá trị nền của trạng thái, hữu ích khi lưu trữ trong cơ sở dữ liệu
- Nhận mã đơn hàng (chuỗi) và một
main.php: Nạp tệp Order. Bạn sẽ nhận hai đầu vào: mã đơn hàng và một chuỗi trạng thái, chẳng hạn"shipped". DùngtryFrom()để chuyển chuỗi đầu vào thành enumOrderStatusmột cách an toàn. Nếu trạng thái hợp lệ, hãy tạo mộtOrdervà in ra hai dòng:- Kết quả của
getInfo() - Kết quả của
getStatusValue()
"Invalid status".- Kết quả của
Thử thách này minh họa cách enum giúp đảm bảo an toàn về kiểu dữ liệu. Lớp Order chỉ có thể nhận các trạng thái hợp lệ, còn phương thức tryFrom() giúp bạn xử lý đầu vào của người dùng an toàn mà không có nguy cơ nhận giá trị không hợp lệ.
Tự làm thử
<?php
require_once 'Order.php';
// Đọc đầu vào
$orderId = trim(fgets(STDIN));
$statusString = trim(fgets(STDIN));
// TODO: Dùng OrderStatus::tryFrom() để chuyển chuỗi trạng thái thành enum một cách an toàn
// tryFrom() trả về null nếu giá trị không hợp lệ
// TODO: Nếu trạng thái hợp lệ, tạo một Order và in ra:
// - Kết quả của getInfo()
// - Kết quả của getStatusValue()
// TODO: Nếu trạng thái không hợp lệ, in ra "Invalid status"
?>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 sinh10Các khái niệm OOP nâng cao
Kết hợp hay kế thừaTiêm phụ thuộcLớp ẩn danhKiểu liệt kê (PHP 8.1)Fiber (PHP 8.1)Tìm hiểu sâu về sao chép đối tượngBộ sinh và bộ lặp2Khô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