Lỗi Gặp Phải
Bạn gọi một hàm nhưng thiếu một hoặc nhiều đối số bắt buộc. PHP dừng thực thi ngay lập tức và ném ra:
Fatal error: Uncaught ArgumentCountError: Too few arguments to function update_user(), 1 passed and exactly 2 expected
Chương trình chết ngay tại chỗ. PHP 7+ đã nâng cấp lỗi này từ một cảnh báo im lặng thành ArgumentCountError thực sự — vì vậy code PHP 5 từng "chạy được" một cách yên lặng giờ sẽ crash thẳng tay.
Nguyên Nhân
Nơi gọi hàm không cung cấp đủ những gì mà signature của hàm yêu cầu. Hai nguyên nhân phổ biến nhất: hàm được thêm một tham số bắt buộc mới sau khi merge hoặc cập nhật, hoặc lời gọi hàm vốn đã thiếu từ đầu nhưng PHP 5 không bao giờ phàn nàn.
Ví dụ gây ra lỗi này:
<?php
function update_user(int $user_id, string $name): bool {
// cập nhật người dùng trong DB
return true;
}
// Sai — chỉ truyền 1 đối số
update_user(42);
// Fatal error: Too few arguments to function update_user(), 1 passed and exactly 2 expected
Cách Sửa 1: Truyền Đủ Đối Số Còn Thiếu
Kiểm tra signature của hàm yêu cầu những gì, sau đó truyền đầy đủ:
<?php
// Đúng — truyền đủ cả 2 đối số bắt buộc
update_user(42, 'John Doe');
Không chắc hàm nhận những tham số nào? Reflection sẽ in ra từng tham số và cho biết nó có phải tùy chọn hay không:
<?php
$ref = new ReflectionFunction('update_user');
foreach ($ref->getParameters() as $param) {
echo '$' . $param->getName();
if ($param->isOptional()) {
echo ' (tùy chọn, mặc định: ' . var_export($param->getDefaultValue(), true) . ')';
} else {
echo ' (bắt buộc)';
}
echo "\n";
}
Cách Sửa 2: Đặt Giá Trị Mặc Định Cho Tham Số
Khi đối số còn thiếu có một giá trị mặc định hợp lý, hãy khai báo nó ngay trong signature của hàm — người gọi sẽ không cần truyền nữa:
<?php
function update_user(int $user_id, string $name = ''): bool {
if ($name === '') {
// lấy từ DB hoặc bỏ qua việc cập nhật tên
}
return true;
}
// Bây giờ cả hai cách gọi đều hợp lệ
update_user(42); // dùng chuỗi rỗng mặc định
update_user(42, 'John'); // dùng tên được truyền vào
Chỉ dùng cách này khi giá trị mặc định rỗng hoặc null thực sự có ý nghĩa. Đừng dùng nó để che đậy dữ liệu còn thiếu.
Cách Sửa 3: Dùng Cú Pháp Variadic Cho Số Lượng Đối Số Linh Hoạt
Khi một hàm hợp lệ cần xử lý bất kỳ số lượng đối số nào, cú pháp variadic là công cụ phù hợp:
<?php
function update_user(int $user_id, string ...$fields): bool {
foreach ($fields as $field) {
// xử lý từng field
}
return true;
}
update_user(42); // không có đối số thêm — hợp lệ
update_user(42, 'name'); // một đối số thêm
update_user(42, 'name', 'email'); // hai đối số thêm
Cách Sửa 4: Kiểm Tra Lời Gọi Method Trên Object
Các method của class cũng ném ra lỗi tương tự. Tìm tên class và method trong stack trace, sau đó áp dụng cách sửa tương tự:
<?php
class UserService {
public function update(int $user_id, array $data): bool {
return true;
}
}
$service = new UserService();
// Sai
$service->update(42);
// Fatal error: Too few arguments to function UserService::update(), 1 passed and exactly 2 expected
// Đúng
$service->update(42, ['name' => 'John']);
Tìm Đúng Vị Trí Gọi Hàm Bị Lỗi
Thông báo lỗi chỉ ra tên hàm nhưng thường bỏ qua nơi nó được gọi từ đâu. Hãy cài một exception handler để hiển thị toàn bộ stack trace:
<?php
// Đặt ở đầu file entry point (chỉ dùng khi dev)
set_exception_handler(function (Throwable $e) {
echo $e->getMessage() . "\n";
echo $e->getTraceAsString();
});
Hoặc theo dõi trực tiếp file error log:
tail -f /var/log/php/error.log
# hoặc cho PHP-FPM:
tail -f /var/log/php8.2-fpm.log
Dù cách nào, bạn cũng sẽ thấy chính xác file và dòng code có lời gọi sai:
#0 /var/www/html/controllers/UserController.php(45): update_user(42)
#1 /var/www/html/index.php(12): UserController->save()
Hành Vi Của PHP 7 So Với PHP 8
Cách PHP xử lý lỗi này đã thắt chặt đáng kể qua các phiên bản — đáng biết nếu bạn đang nâng cấp code cũ:
- PHP 5.x: Đối số còn thiếu kích hoạt
E_WARNING. Thực thi vẫn tiếp tục với tham số thiếu được đặt thầm lặng thànhnull. - PHP 7.0+: Ném ra
ArgumentCountError(kế thừa từTypeError). Fatal nếu không được bắt. - PHP 8.x: Hành vi giống PHP 7, nhưng nay các hàm nội bộ của PHP cũng ném ra
ArgumentCountErrorkhi thiếu đối số.
Đang chuyển codebase PHP 5 lên PHP 7+? Hãy chuẩn bị tinh thần gặp lỗi này xuất hiện ở những lời gọi đã bị hỏng âm thầm suốt nhiều năm.
Kiểm Tra Lại Sau Khi Sửa
Chạy kiểm tra nhanh sau khi đã thực hiện thay đổi:
# Chạy script từ CLI
php -f your_script.php
# Hoặc kiểm tra cú pháp trước
php -l your_script.php
Trên Laravel hoặc Symfony, hãy gọi đúng route hoặc lệnh artisan từng bị crash. Không còn fatal error trong log là xong.
Phòng Ngừa
- Strict types: Thêm
declare(strict_types=1);ở đầu các file. Nó không ngăn trực tiếp lỗi thiếu đối số, nhưng tính kỷ luật về kiểu dữ liệu sẽ phát hiện sự không khớp sớm hơn. - Phân tích tĩnh: PHPStan hoặc Psalm phát hiện lỗi thiếu đối số trước khi code chạy:
vendor/bin/phpstan analyse src/ --level=5 - Unit tests: Một test gọi hàm với đúng đối số sẽ báo lỗi ngay lập tức nếu ai đó thay đổi signature.
- PHPDoc: Ghi lại tham số bắt buộc và tùy chọn bằng block
@param— IDE của bạn sẽ cảnh báo khi bạn gõ lời gọi sai.

