Sửa lỗi PHP Fatal error: Uncaught ArgumentCountError: Too few arguments to function

beginner🐘 PHP2026-07-07| PHP 7.0+ trên Linux/Windows/macOS (Apache, Nginx, CLI)

Error Message

Fatal error: Uncaught ArgumentCountError: Too few arguments to function update_user(), 1 passed and exactly 2 expected
#php#function#arguments#error

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ành null.
  • 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 ArgumentCountError khi 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.

Related Error Notes