Menu

Biểu thức match trong PHP: match và switch, match(true)

match ($x) { 1, 2 => 'low', default => 'other' } so sánh một giá trị bằng === nghiêm ngặt, trả về kết quả của nhánh khớp đầu tiên và ném ra UnhandledMatchError khi không nhánh nào khớp. Gồm match so với switch, match(true) và match với enum.

Trang này có trình soạn thảo chạy trực tiếp. Sửa, chạy và xem đầu ra ngay lập tức.

match ($value) { ... } so sánh một giá trị với danh sách các nhánh bằng === nghiêm ngặt và trả về kết quả của nhánh khớp đầu tiên. Nhiều giá trị có thể dùng chung một nhánh, default nhận phần còn lại, và nếu không có gì khớp, PHP ném ra UnhandledMatchError.

Để ý dấu chấm phẩy sau dấu ngoặc nhọn đóng: match là một biểu thức (expression), giống 1 + 2, nên cả khối là một câu lệnh gán. Mỗi nhánh có dạng values => result, cách nhau bằng dấu phẩy, và được phép có dấu phẩy sau nhánh cuối cùng.

Nhiều giá trị trong một nhánh

Liệt kê các giá trị, cách nhau bằng dấu phẩy. Nhánh khớp nếu giá trị cần so sánh giống hệt (===) một trong số đó.

Trả về match trực tiếp từ một hàm, như ở đây, là cách dùng phổ biến nhất.

match và switch

Cùng một phép ánh xạ viết theo hai cách, với một đầu vào cho thấy khác biệt lớn nhất: phép so sánh. switch dùng ==, nên chuỗi "1" khớp với case 1. match dùng ===, nên không khớp.

matchswitch
So sánhnghiêm ngặt ===lỏng ==
Kết quảtrả về một giá trịcâu lệnh, không trả về gì
Rơi xuống nhánh saukhông bao giờcó, cho đến break
Nhiều giá trị1, 2 =>xếp chồng case 1: case 2:
Không khớpném ra UnhandledMatchErrorkhông làm gì
Thân một nhánhmột biểu thứcbao nhiêu câu lệnh cũng được

Dùng match khi bạn chuyển một giá trị thành giá trị khác. Giữ switch khi một nhánh cần nhiều câu lệnh hoặc khi bạn cố ý cho rơi xuống nhánh sau; trang switch có cả hai trường hợp.

UnhandledMatchError: khi không nhánh nào khớp

Không có nhánh default, một giá trị không khớp gì là lỗi, chứ không lặng lẽ thành null. Đó là một tính năng: một mã trạng thái mới hay một lỗi gõ sẽ báo lỗi rõ ràng thay vì lọt qua.

PHP dừng với PHP Fatal error: Uncaught UnhandledMatchError: Unhandled match case of type string. Môi trường phát triển (với zend.exception_ignore_args tắt) thì nêu luôn giá trị: Unhandled match case 'XL'. Sửa bằng cách thêm default => 'other', hoặc bắt lỗi ở chỗ có thể gặp giá trị lạ:

match(true) cho khoảng giá trị và điều kiện

match so sánh giá trị đầu vào với từng nhánh, nên nếu giá trị đó là true thì mỗi nhánh có thể là một điều kiện. Điều kiện đầu tiên cho kết quả đúng bằng true sẽ thắng.

Có hai chi tiết trong khối trên. throw là một biểu thức từ PHP 8, nên nó có thể là kết quả của một nhánh. Và vì phép so sánh là nghiêm ngặt, mỗi điều kiện phải trả về một boolean thật: một nhánh như $name => ... không bao giờ khớp true kể cả khi $name là chuỗi khác rỗng. Chỉ nhánh khớp mới được tính, nên throw chỉ chạy khi tuổi là số âm.

match với enum

match và enum rất hợp nhau: bên trong một phương thức của enum, match ($this) ánh xạ từng case sang một giá trị. Xem enum trong PHP để tìm hiểu về chính enum.

Ở đây cố ý không có default. Nếu sau này ai đó thêm case thứ năm, gọi color() trên case đó sẽ ném lỗi thay vì trả về một màu sai.

Nhiều câu lệnh trong một nhánh

Một nhánh chỉ chứa một biểu thức, nên 'save' => { ...; ... } không phải PHP hợp lệ. Chuyển phần việc vào một hàm rồi gọi nó từ nhánh. Hàm của các nhánh không khớp sẽ không bao giờ được gọi.

Đổi $format thành 'json' hoặc 'xml' rồi chạy lại.

Câu hỏi thường gặp

match và switch trong PHP khác nhau thế nào?

match so sánh bằng === nghiêm ngặt, trả về một giá trị, không bao giờ rơi xuống nhánh tiếp theo, nhận nhiều giá trị cách nhau bằng dấu phẩy trong một nhánh và ném ra UnhandledMatchError khi không nhánh nào khớp. switch so sánh lỏng bằng ==, là một câu lệnh không trả về gì, rơi xuống case sau nếu thiếu break và lặng lẽ không làm gì khi không case nào khớp.

Chuyện gì xảy ra khi không nhánh nào trong biểu thức match của PHP khớp?

PHP ném ra UnhandledMatchError. Thêm nhánh default => ... để xử lý mọi giá trị còn lại, hoặc bắt lỗi bằng try { ... } catch (\UnhandledMatchError $e) { ... }.

Làm sao dùng match với điều kiện như lớn hơn trong PHP?

So khớp với true: match (true) { $age < 13 => 'child', $age < 18 => 'teen', default => 'adult' }. Mỗi nhánh là một điều kiện, và điều kiện đầu tiên có giá trị đúng bằng true sẽ thắng.

Một nhánh match trong PHP có chạy được nhiều câu lệnh không?

Không, mỗi nhánh chỉ là một biểu thức. Đặt các câu lệnh vào một hàm hoặc phương thức rồi gọi nó từ nhánh, ví dụ 'export' => exportCsv($rows).

PHP phiên bản nào thêm match?

PHP 8.0. Trên PHP 7, cùng logic đó cần câu lệnh switch hoặc tra cứu trong mảng như $labels[$status] ?? 'Unknown'.

Hình minh họa các ngôn ngữ lập trình của Coddy

Học lập trình cùng Coddy

Bắt đầu