Một hàm (function) trong PHP được định nghĩa bằng từ khóa function, một cái tên, danh sách tham số và phần thân; return gửi một giá trị về cho nơi gọi. function add(int $a, int $b): int { return $a + $b; } định nghĩa hàm, còn add(2, 3) gọi hàm và trả về 5.
string và int đặt trước các tham số là khai báo kiểu, còn : string sau dấu ngoặc tròn là kiểu trả về. Cả hai đều không bắt buộc, nhưng chúng giúp bắt lỗi sớm và cho biết hàm mong đợi điều gì.
Giá trị trả về và trả về nhiều giá trị
return kết thúc hàm ngay lập tức. Một hàm không có return, hoặc chỉ có return; trơn, sẽ trả về null; hãy khai báo : void khi hàm chỉ được gọi để thực hiện một tác dụng. Một hàm chỉ trả về một giá trị, nhưng giá trị đó có thể là một mảng, và bạn destructure nó ở phía gọi:
Xem destructuring mảng để biết các dạng khác của [...] =.
Tham số mặc định và đối số có tên
Một tham số có = value là tham số tùy chọn: nơi gọi có thể bỏ qua nó. Tham số tùy chọn đặt sau các tham số bắt buộc. Từ PHP 8.0, đối số có tên cho phép nơi gọi truyền bất kỳ tham số nào theo tên, nhờ vậy bạn bỏ qua được những tham số tùy chọn không cần đến.
Đối số có tên cũng giúp lời gọi các hàm có sẵn dễ đọc hơn: str_pad('7', 3, '0', pad_type: STR_PAD_LEFT). Tên tham số trở thành một phần giao diện công khai của hàm, nên đổi tên tham số có thể làm hỏng những nơi gọi đang dùng tên.
Truyền tham chiếu
Thông thường PHP truyền một bản sao của mỗi đối số, nên hàm không thể thay đổi biến của nơi gọi. Dấu & trước tham số sẽ truyền chính biến đó. Các hàm có sẵn như sort() hoạt động theo cách này.
Trả về một giá trị mới thường rõ ràng hơn là sửa đối số. Chỉ dùng tham chiếu khi hàm thật sự được thiết kế để sửa một thứ tại chỗ.
Khai báo kiểu và strict_types
Mặc định, PHP chuyển đối số sang kiểu đã khai báo khi có thể: add("5", 3) biến "5" thành 5. Đặt declare(strict_types=1); ở ngay đầu tệp sẽ tắt việc đó cho các lời gọi trong tệp này, nên sai kiểu sẽ ném ra TypeError thay vì được chuyển đổi.
Không có dòng declare, cùng lời gọi đó in ra 8. Các chuỗi không phải số, như "five", ném ra TypeError ở cả hai chế độ.
Các kiểu bạn có thể khai báo cho tham số và giá trị trả về:
never là kiểu trả về cho những hàm luôn ném ngoại lệ hoặc thoát chương trình. Tên lớp và interface cũng dùng được làm kiểu.
Số lượng đối số thay đổi với ...$args
...$numbers gom bất kỳ số lượng đối số nào vào một mảng. Cũng dấu ... đó ở phía gọi sẽ trải một mảng ra thành các đối số riêng lẻ.
Dùng biến bên ngoài trong một hàm
Một hàm có phạm vi riêng. Biến định nghĩa bên ngoài không nhìn thấy được ở bên trong, điều khiến những người quen JavaScript bất ngờ:
<?php
$taxRate = 0.2;
function priceWithTax(float $price): float
{
return $price * (1 + $taxRate); // $taxRate is undefined here
}
Warning: Undefined variable $taxRate in /path/to/index.php on line 6
và hàm trả về giá chưa cộng thuế. Thay vào đó, hãy truyền giá trị vào qua tham số. Cách này giúp hàm thể hiện rõ nó phụ thuộc vào gì và dễ kiểm thử:
Từ khóa global cũng dùng được, nhưng nó che giấu sự phụ thuộc; phạm vi biến có nói về nó. Với những hàm ngắn được truyền cho hàm khác, như callback của array_map(), xem hàm ẩn danh, loại hàm có thể giữ lại biến bên ngoài bằng use.
Câu hỏi thường gặp
Làm sao định nghĩa một hàm trong PHP?
Dùng từ khóa function, một cái tên, danh sách tham số trong ngoặc tròn và phần thân: function add(int $a, int $b): int { return $a + $b; }. Gọi hàm bằng add(2, 3). Tên hàm không phân biệt hoa thường, và một hàm định nghĩa ở cấp cao nhất của tệp có thể được gọi trước cả dòng định nghĩa nó.
Làm sao trả về nhiều giá trị từ một hàm PHP?
Trả về một mảng rồi destructure nó: function minMax(array $a): array { return [min($a), max($a)]; } rồi [$min, $max] = minMax([3, 1, 4]);. Muốn kết quả có tên, hãy trả về mảng kết hợp và dùng ['min' => $min] = ....
declare(strict_types=1) có tác dụng gì?
Nó tắt việc tự động chuyển kiểu cho các lời gọi hàm trong tệp đó, nên truyền "5" vào tham số int sẽ ném ra TypeError thay vì chuyển thành 5. Câu lệnh này phải là câu lệnh đầu tiên của tệp và chỉ ảnh hưởng đến tệp đó.
Đối số có tên (named arguments) trong PHP là gì?
Từ PHP 8.0, bạn có thể truyền đối số theo tên tham số: htmlspecialchars($s, double_encode: false). Chúng có thể đặt theo bất kỳ thứ tự nào sau các đối số theo vị trí, và cho phép bỏ qua những tham số tùy chọn bạn không muốn đổi.
Làm sao truyền biến theo tham chiếu trong PHP?
Đặt & trước tham số: function addOne(int &$n): void { $n++; }. Khi đó hàm thay đổi chính biến của nơi gọi. Không có &, PHP truyền một bản sao và biến của nơi gọi giữ nguyên.