Tại sao trang web của bạn bị lỗi
Nâng cấp lên PHP 8.0 trở lên rất tốt cho hiệu năng, nhưng đây là một thay đổi gây phá vỡ cấu trúc (breaking change) đối với các mã nguồn cũ. Nếu bạn thấy màn hình trắng hoặc nhật ký lỗi fatal error, trang web của bạn có khả năng đang phụ thuộc vào một hàm cũ gọi là create_function(). Hàm này đã chính thức bị loại bỏ trong PHP 8.0.
Fatal error: Uncaught Error: Call to undefined function create_function() in /path/to/wp-content/plugins/old-plugin/filename.php:line_number
Nguyên nhân gốc rễ
PHP 7.2 đã ngừng hỗ trợ (deprecated) create_function() từ năm 2017. Nó chậm và không an toàn vì bên trong sử dụng eval(), cho phép thực thi các chuỗi mã tùy ý. Vì rủi ro bảo mật này, PHP 8.0 cuối cùng đã xóa nó khỏi nhân hệ thống. Nếu một plugin hoặc theme được viết từ năm hoặc sáu năm trước vẫn còn hoạt động trên trang web của bạn, nó sẽ gặp lỗi ngay khi bạn chuyển sang PHP 8.
Bước 1: Xác định vị trí mã bị lỗi
Bạn cần tìm tệp cụ thể gây ra xung đột. Nếu trình duyệt của bạn chỉ hiển thị thông báo "Critical Error" chung chung, bạn sẽ cần kiểm tra nhật ký lỗi hoặc bật chế độ gỡ lỗi của WordPress. Điều này sẽ tiết lộ "bằng chứng rõ ràng".
Mở tệp wp-config.php của bạn và cập nhật các dòng sau:
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', true );
Tải lại trang web của bạn. Lỗi bây giờ sẽ chỉ trực tiếp đến đường dẫn tệp, thường là bên trong wp-content/plugins/ hoặc wp-content/themes/. Hãy ghi lại tên tệp và số dòng được đề cập.
Bước 2: Cập nhật mọi thứ
Trước khi chạm vào bất kỳ mã nguồn nào, hãy kiểm tra các bản cập nhật. Hầu hết các nhà phát triển uy tín đã vá lỗi này từ nhiều năm trước. Nếu bạn đang sử dụng phiên bản của một plugin phổ biến như Slider Revolution hoặc LayerSlider từ năm 2018, chỉ cần cập nhật lên phiên bản mới nhất sẽ giải quyết vấn đề ngay lập tức.
- Công cụ trả phí (Premium): Đăng nhập vào chợ ứng dụng (như ThemeForest) để tải xuống các tệp tương thích với PHP 8 mới nhất.
- Plugin bị bỏ rơi: Nếu một plugin đã không được cập nhật trong hơn 3 năm, đó là một rủi ro bảo mật. Hãy chuyển sang một giải pháp thay thế hiện đại thay vì cố gắng vá lỗi nó.
Bước 3: Cấu trúc lại thủ công sang Hàm ẩn danh
Nếu bạn đang mắc kẹt với mã tùy chỉnh không thể thay thế, bạn phải viết lại hàm đó. Bạn cần chuyển đổi create_function dựa trên chuỗi cũ thành hàm ẩn danh PHP hiện đại (còn được gọi là closure).
Ví dụ 1: Logic Filter đơn giản
Mã cũ (Bị lỗi):
add_filter('excerpt_length', create_function('$a', 'return 25;'));
Mã mới (Đã sửa):
add_filter('excerpt_length', function($a) {
return 25;
});
Ví dụ 2: Logic phức tạp với các đối số
Mã cũ (Bị lỗi):
$new_func = create_function('$val', 'return my_custom_logic($val) . "_suffix";');
add_filter('some_hook', $new_func);
Mã mới (Đã sửa):
$new_func = function($val) {
return my_custom_logic($val) . "_suffix";
};
add_filter('some_hook', $new_func);
Ví dụ 3: Truyền biến bằng 'use'
Phần khó nhất của create_function là cách nó xử lý các biến bên ngoài. Trong PHP hiện đại, chúng ta sử dụng từ khóa use để đưa những biến đó vào phạm vi của hàm.
Mã cũ (Bị lỗi):
$suffix = '_test';
add_filter('wp_title', create_function('$title', 'return $title . "' . $suffix . '";'));
Mã mới (Đã sửa):
$suffix = '_test';
add_filter('wp_title', function($title) use ($suffix) {
return $title . $suffix;
});
Bước 4: Xác minh và dọn dẹp
Sau khi lưu các thay đổi, hãy thực hiện kiểm tra nhanh tình trạng trang web:
- Xóa Cache: Xóa bộ nhớ đệm máy chủ và bất kỳ plugin nào như WP Rocket.
- Kiểm tra Site Health: Đi tới Tools > Site Health trong bảng điều khiển của bạn để đảm bảo không còn lỗi PHP nào khác.
- Tắt chế độ Debug: Khi trang web đã ổn định, hãy đặt
WP_DEBUGtrở lại thànhfalsetrong tệpwp-config.phpđể tránh làm đầy nhật ký lỗi.
Đảm bảo trang web của bạn luôn sẵn sàng cho tương lai
Đừng để bị bất ngờ bởi bản cập nhật PHP tiếp theo. Hãy sử dụng môi trường staging để thử nghiệm các bước nhảy vọt về phiên bản chính (như chuyển từ 8.1 sang 8.2). Nếu bạn thấy các thông báo "Deprecated" trong nhật ký lỗi, hãy xử lý chúng ngay lập tức. Những cảnh báo này là dấu hiệu sớm cho thấy một hàm sẽ bị xóa trong bản phát hành lớn tiếp theo, giúp bạn có nhiều thời gian để cấu trúc lại mã mà không phải chịu áp lực khi trang web bị sập.

