Arrow function là một hàm ẩn danh ngắn gọn: fn($x) => $x * 2. Phần thân sau => là một biểu thức duy nhất và giá trị của nó được trả về; biến nào ở đoạn code bao quanh mà biểu thức dùng đến đều được bắt tự động, theo giá trị. Arrow function có từ PHP 7.4 và chủ yếu được dùng làm callback.
Cú pháp
fn, danh sách tham số, =>, một biểu thức. Kiểu tham số, giá trị mặc định và kiểu trả về hoạt động giống như ở hàm thông thường:
Không có từ khóa return và không có dấu ngoặc nhọn. Bạn vẫn có thể ngắt một biểu thức dài thành nhiều dòng cho dễ đọc.
Biến bên ngoài được bắt theo giá trị
Arrow function thấy mọi biến của phạm vi nơi nó được tạo ra. Nó sao chép giá trị của các biến đó ngay tại thời điểm ấy. Thay đổi bên trong chỉ nằm bên trong, còn thay đổi bên ngoài sau khi hàm đã được tạo thì hàm không thấy:
Đây là khác biệt chính so với function () use (&$count), vốn có thể dùng chung một biến theo tham chiếu. Arrow function không gán lại được biến bên ngoài. Nó vẫn có thể thay đổi một đối tượng đã bắt (bản sao là một handle trỏ tới cùng đối tượng), và một tham số khai báo theo tham chiếu hoạt động như ở mọi hàm khác: fn(array &$list) => $list[] = 'x'.
Callback cho array_map, array_filter và usort
Phần lớn các hàm mảng nhận một callback, và đó là nơi arrow function giúp code gọn nhất. Hãy so sánh cùng một phép lọc viết theo hai cách:
<=> trả về -1, 0 hoặc 1, đúng thứ mà usort() cần, nên sắp xếp theo một trường chỉ cần một dòng. Đổi chỗ $a và $b để sắp xếp giảm dần.
Arrow function trả về arrow function
Các biến được bắt bao gồm cả tham số của arrow function bao ngoài, nên bạn có thể lồng chúng vào nhau để tạo hàm từ các giá trị khác:
Lưu ý rằng array_filter() giữ nguyên khóa gốc, vì vậy kết quả bắt đầu ở chỉ số 1.
fn và function: khi nào cần closure đầy đủ
Arrow function không còn phù hợp khi phần thân cần nhiều hơn một biểu thức hoặc phải thay đổi biến bên ngoài. Lúc đó hãy dùng hàm ẩn danh:
fn($x) => ... | function ($x) use ($y) { ... } | |
|---|---|---|
| Thân hàm | một biểu thức | câu lệnh bất kỳ |
| Trả về | tự động | return rõ ràng |
| Biến bên ngoài | mọi biến được dùng, tự động | chỉ những biến liệt kê trong use |
| Bắt theo tham chiếu | không | có, use (&$y) |
| Có từ phiên bản | PHP 7.4 | PHP 5.3 |
Khi arrow function trở nên chật chội, thường đó là dấu hiệu công việc thực ra gồm hai việc. Tách nó thành một phép lọc và một phép tính tổng như trên giúp mỗi callback chỉ còn một biểu thức.
Câu hỏi thường gặp
Arrow function trong PHP là gì?
Là một hàm ẩn danh ngắn gọn có từ PHP 7.4: fn($x) => $x * 2. Thân hàm là một biểu thức duy nhất, giá trị của nó được trả về tự động, và hàm đọc được biến ở phạm vi bên ngoài mà không cần mệnh đề use.
Arrow function trong PHP có viết được nhiều dòng không?
Không. Phần thân sau => phải là một biểu thức; không có khối lệnh chứa nhiều câu lệnh. Bạn có thể ngắt một biểu thức dài thành nhiều dòng, nhưng nếu cần if, vòng lặp hay nhiều câu lệnh, hãy dùng function () use (...) { ... }.
Arrow function có sửa được biến bên ngoài không?
Không. Arrow function bắt biến bên ngoài theo giá trị, nên fn() => $count++ chỉ thay đổi bản sao của riêng nó, còn $count bên ngoài giữ nguyên. Để sửa biến bên ngoài, dùng closure với use (&$count).
fn và function trong PHP khác nhau thế nào?
fn($x) => ... chứa một biểu thức, tự trả về giá trị đó và bắt theo giá trị mọi biến bên ngoài mà nó dùng. function ($x) use ($y) { ... } chứa được câu lệnh bất kỳ, cần return rõ ràng, và chỉ thấy các biến liệt kê trong use, những biến này có thể được bắt theo tham chiếu.