Sửa lỗi PHP Fatal Error: Call to undefined function — 4 Nguyên nhân và Cách khắc phục

intermediate🐘 PHP2026-03-19| PHP 7.x/8.x trên Linux (Ubuntu/Debian/CentOS), Windows (WAMP/XAMPP), macOS — Apache hoặc Nginx + PHP-FPM

Error Message

Fatal error: Uncaught Error: Call to undefined function
#php#function#undefined#extension

Lỗi Gặp Phải

Fatal error: Uncaught Error: Call to undefined function some_function() in /var/www/html/app.php:42
Stack trace:
#0 {main}
  thrown in /var/www/html/app.php on line 42

Tên hàm xuất hiện sau "Call to undefined function" sẽ cho bạn biết tất cả. curl_init → thiếu extension. myhelper → thiếu include. Đọc kỹ toàn bộ thông báo lỗi trước khi làm bất cứ điều gì — cái tên đó chính là toàn bộ manh mối điều tra của bạn.

Nguyên Nhân Gốc Rễ

Có bốn nguyên nhân gây ra lỗi này — và chỉ bốn thôi:

  • Một PHP extension cung cấp hàm đó chưa được bật trên máy chủ này
  • File định nghĩa hàm chưa bao giờ được include
  • Sai namespace — hàm toàn cục cần tiền tố \ khi dùng bên trong một namespace
  • Gõ nhầm tên hàm, hoặc hàm đó không tồn tại trong phiên bản PHP của bạn

Cách Sửa 1: Bật Extension Bị Thiếu

Máy chủ mới, triển khai mới, máy của thành viên mới trong nhóm — đây là nguyên nhân phổ biến nhất. Đâu đó trong quá trình chuyển từ môi trường cũ sang môi trường mới, một PHP extension đã bị bỏ lại. Hãy kiểm tra xem hàm không xác định có thuộc một extension đã biết không:

  • curl_init() → curl
  • imagecreate() → gd
  • mb_strlen() → mbstring
  • sodium_crypto_secretbox() → sodium
  • ldap_connect() → ldap
  • zip_open() → zip

Kiểm tra những gì đang được tải:

php -m | grep curl

Hoặc xác minh từ code PHP:

<?php
var_dump(extension_loaded('curl'));

Cài đặt và bật trên Ubuntu/Debian:

sudo apt install php8.2-curl php8.2-gd php8.2-mbstring
sudo systemctl restart php8.2-fpm
# hoặc với Apache
sudo systemctl restart apache2

Trên CentOS/RHEL:

sudo dnf install php-curl php-gd php-mbstring
sudo systemctl restart php-fpm

Thích chỉnh sửa php.ini trực tiếp? Tìm file đang hoạt động trước, rồi bỏ comment dòng extension:

# Tìm file php.ini đang hoạt động
php --ini | grep "Loaded Configuration"

# Bỏ comment dòng tương ứng
extension=curl
extension=gd
extension=mbstring

Khởi động lại web server sau bất kỳ thay đổi php.ini nào — extension sẽ không được tải nếu không làm vậy.

Cách Sửa 2: Thêm Include Bị Thiếu

Các hàm tự viết và thư viện bên thứ ba không tự nạp chính mình. Nếu PHP chưa thấy file định nghĩa một hàm, hàm đó đơn giản là không tồn tại lúc chạy. Kiểm tra phần đầu của file đang bị lỗi:

<?php
// Phải đặt trước khi gọi hàm
require_once __DIR__ . '/helpers/user-functions.php';

// Bây giờ đoạn này hoạt động
create_user($data);

Với Composer, một dòng bị thiếu sẽ phá hỏng nhiều lần triển khai hơn bất cứ thứ gì khác — đó là autoloader:

<?php
// Thường bị thiếu khi triển khai mới
require_once __DIR__ . '/vendor/autoload.php';

// Bây giờ các package Composer được phân giải đúng
$client = new GuzzleHttp\Client();

Cũng hãy kiểm tra thứ tự các include. PHP đọc file từ trên xuống dưới — bạn không thể gọi một hàm trước khi file chứa nó được tải.

Cách Sửa 3: Sửa Lỗi Namespace

Bên trong một namespace, PHP tìm kiếm hàm trong namespace đó trước. Nó sẽ không tự động quay lại phạm vi toàn cục. Các hàm có sẵn và hàm từ extension cần tiền tố dấu gạch chéo ngược để buộc tra cứu ở namespace toàn cục:

<?php
namespace App\Services;

// LỖI — PHP tìm App\Services\array_map()
$result = array_map('strtolower', $items);

// ĐÚNG — dấu gạch chéo ngược buộc dùng namespace toàn cục
$result = \array_map('strtolower', $items);

Các hàm từ extension cũng gặp vấn đề tương tự:

<?php
namespace App\Http;

// Lỗi
$ch = curl_init($url);

// Đúng
$ch = \curl_init($url);

Rải dấu gạch chéo ngược khắp nơi sẽ nhanh chóng gây rối. Cách sửa gọn hơn — khai báo use function ở đầu file một lần:

<?php
namespace App\Http;

use function curl_init;
use function curl_setopt;
use function curl_exec;

$ch = curl_init($url); // Hoạt động rồi

Cách Sửa 4: Sai Phiên Bản PHP Hoặc Gõ Nhầm

Một số hàm bị giới hạn theo phiên bản. str_contains() có từ PHP 8.0. array_is_list() xuất hiện từ PHP 8.1. Nếu bạn đang chạy 7.4 mà gọi một trong hai hàm đó, bạn sẽ gặp lỗi này. Kiểm tra phiên bản trước:

php --version

Xác nhận xem hàm có tồn tại không:

php -r "var_dump(function_exists('str_contains'));"

Bị kẹt với phiên bản PHP cũ? Một polyfill sẽ giúp bạn thoát khỏi tình trạng đó trong chưa đầy một phút:

<?php
if (!function_exists('str_contains')) {
    function str_contains(string $haystack, string $needle): bool {
        return $needle === '' || strpos($haystack, $needle) !== false;
    }
}

Với lỗi gõ nhầm, hãy grep toàn bộ codebase để tìm nơi hàm lẽ ra phải được định nghĩa:

grep -r "function the_function_name" /var/www/html/

Xác Nhận Đã Sửa Xong

Đừng đoán mò trên trình duyệt. Xác nhận từ CLI trước:

# Kiểm tra extension đã được tải chưa
php -r "echo extension_loaded('curl') ? 'curl: OK' : 'curl: MISSING';"
# Kiểm tra hàm có thể truy cập không
php -r "echo function_exists('curl_init') ? 'OK' : 'MISSING';"
# Quét output phpinfo để tìm extension
php -r "phpinfo();" | grep -i curl

Trong môi trường phát triển, thêm một đoạn kiểm tra trước lệnh gọi có vấn đề. Bạn sẽ nhận được thông báo lỗi rõ ràng, cụ thể thay vì một trang 500 vô nghĩa:

<?php
if (!function_exists('curl_init')) {
    throw new \RuntimeException('curl extension not loaded — install php-curl and restart your server');
}

Phòng Ngừa

Khai báo các yêu cầu PHP extension trong composer.json. Bằng cách này, composer install sẽ thất bại ngay lập tức trên một máy chủ cấu hình sai — một cách rõ ràng, với thông báo cụ thể — thay vì lúc chạy khi người dùng truy cập trang:

{
  "require": {
    "php": "^8.1",
    "ext-curl": "*",
    "ext-mbstring": "*",
    "ext-gd": "*"
  }
}

Thêm một đoạn kiểm tra lúc khởi động trong file khởi tạo ứng dụng của bạn cho những thứ quan trọng:

<?php
$required = ['curl', 'mbstring', 'pdo_mysql', 'gd'];
foreach ($required as $ext) {
    if (!extension_loaded($ext)) {
        throw new \RuntimeException("Missing required PHP extension: {$ext}");
    }
}

Dùng Docker? Cài đặt tất cả các extension cần thiết một cách tường minh trong Dockerfile của bạn. Khi môi trường dev và production dùng chung một image, lỗi này sẽ không còn xuất hiện trên các máy chủ mới lúc 2 giờ sáng nữa.

Related Error Notes