Sửa lỗi PHP Warning: PHP Startup: Unable to load dynamic library — Extension Không Tìm Thấy

beginner🐘 PHP2026-05-31| Ubuntu 20.04/22.04, Debian 11/12, CentOS 7/8, PHP 7.4 / 8.0 / 8.1 / 8.2 — CLI, FPM và Apache mod_php

Error Message

PHP Warning: PHP Startup: Unable to load dynamic library 'extension_name' (tried: /usr/lib/php/...)
#php#php.ini#extension#cấu hình

TL;DR

PHP đang cố tải một extension được khai báo trong php.ini, nhưng file .so bị thiếu, nằm sai vị trí, hoặc được biên dịch cho phiên bản PHP khác. Hãy cài extension còn thiếu, comment out dòng khai báo lỗi thời trong php.ini, hoặc sửa lại đường dẫn.

Chuyện Gì Đã Xảy Ra

Bạn đang nhìn chằm chằm vào dòng lỗi này trong log lúc 2 giờ sáng:

PHP Warning: PHP Startup: Unable to load dynamic library 'redis.so' (tried: /usr/lib/php/20210902/redis.so (/usr/lib/php/20210902/redis.so: cannot open shared object file: No such file or directory), /usr/lib/php/20210902/redis.so.so (/usr/lib/php/20210902/redis.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0

PHP đọc extension=redis.so (hoặc extension=redis) từ php.ini hoặc một file trong /etc/php/8.1/conf.d/, nhưng file .so lại không tồn tại trên đĩa. Có ba tình huống dẫn đến lỗi này:

  • Extension chưa bao giờ được cài — ai đó đã thêm dòng khai báo vào php.ini nhưng chưa bao giờ chạy apt install.
  • PHP đã được nâng cấp — thư mục extension thay đổi (ví dụ: 2020093020210902), các file .so cũ đã biến mất, còn file mới chưa được cài.
  • Extension bị xóa thủ công — package đã bị gỡ nhưng dòng khai báo trong php.ini vẫn còn đó.

Bước 1 — Xác Định Extension Bị Lỗi

Chạy PHP từ dòng lệnh để xem tất cả cảnh báo khởi động cùng lúc:

php -v 2>&1 | head -20
# hoặc ép hiện tất cả cảnh báo:
php -r "echo 'ok';" 2>&1

Ghi lại tên extension và đường dẫn PHP đã thử. Sau đó kiểm tra xem file có tồn tại không:

# Thay 'redis.so' và đường dẫn bằng thông tin từ lỗi của bạn
ls -la /usr/lib/php/20210902/redis.so

Tìm tất cả các file ini PHP đang hoạt động — dòng khai báo extension có thể nằm ở bất kỳ đâu:

php --ini
# Hiển thị: Loaded Configuration File + Additional .ini files

# Tìm trong tất cả chúng theo tên extension bị lỗi
grep -r "extension=redis" /etc/php/

Cách Sửa 1 — Cài Extension Còn Thiếu

Nếu extension chưa được cài, hãy cài từ package manager của distro. Luôn khớp với phiên bản PHP đang dùng:

# Ubuntu / Debian
sudo apt update
sudo apt install php8.1-redis   # ví dụ redis
sudo apt install php8.1-gd php8.1-mbstring php8.1-curl  # các extension phổ biến

# CentOS / RHEL (với Remi repo)
sudo dnf install php81-php-redis

# Sau khi cài, kiểm tra file .so đã vào đúng chỗ chưa
ls /usr/lib/php/$(php -r 'echo PHP_MAJOR_VERSION.PHP_MINOR_VERSION . "0" . (PHP_MAJOR_VERSION >= 8 ? "" : "");')/

Khởi động lại PHP-FPM hoặc Apache để áp dụng:

sudo systemctl restart php8.1-fpm
# hoặc
sudo systemctl restart apache2

Cách Sửa 2 — Xóa Dòng Khai Báo Lỗi Thời Trong php.ini

Nếu bạn đã gỡ extension một cách có chủ ý và không còn cần nữa, hãy comment out dòng khai báo thay vì để nó spam log mãi:

# Tìm file chứa dòng khai báo
grep -rl "extension=redis" /etc/php/8.1/

# Chỉnh sửa và comment dòng đó lại
sudo nano /etc/php/8.1/mods-available/redis.ini
# Đổi:  extension=redis.so
# Thành: ;extension=redis.so

Trên hệ thống Debian/Ubuntu, cách sạch hơn là vô hiệu hóa module link:

sudo phpdismod redis
sudo systemctl restart php8.1-fpm

Cách Sửa 3 — Sai Phiên Bản PHP Sau Khi Nâng Cấp

Đây là nguyên nhân phổ biến nhất trên môi trường production. Bạn nâng cấp từ PHP 8.0 lên 8.1, và thư mục extension thay đổi từ 20200930 sang 20210902. Các file .so cũ không được chuyển sang tự động.

Kiểm tra phiên bản API mà PHP của bạn yêu cầu:

php -i | grep 'PHP Extension'
# Kết quả: PHP Extension => 20210902

Sau đó cài lại tất cả extension cho phiên bản mới:

# Liệt kê những gì đã cài cho phiên bản cũ
dpkg -l | grep php8.0

# Cài lại cho phiên bản mới
sudo apt install php8.1-{mysql,redis,gd,mbstring,curl,xml,zip}

Nếu bạn đã biên dịch extension thủ công qua PECL, bạn cần biên dịch lại:

sudo pecl uninstall redis
sudo pecl install redis
# Hoặc chỉ định phiên bản cụ thể
sudo pecl install redis-5.3.7

Cách Sửa 4 — Đường Dẫn Extension Sai Trong php.ini

Nếu ai đó đã hardcode đường dẫn tuyệt đối vào directive extension, nó sẽ bị lỗi khi mọi thứ thay đổi vị trí:

# Sai (đường dẫn hardcode)
extension=/usr/lib/php/20200930/redis.so

# Đúng (chỉ cần tên — PHP tự giải quyết đường dẫn qua extension_dir)
extension=redis.so
# hoặc ngắn hơn nữa
extension=redis

Kiểm tra extension_dir mà PHP đang thực sự dùng:

php -i | grep extension_dir
# extension_dir => /usr/lib/php/20210902

Kiểm Tra Sau Khi Sửa

# Không còn cảnh báo khởi động nữa
php -r "echo 'clean';" 2>&1

# Xác nhận extension đã được tải
php -m | grep redis

# Hoặc kiểm tra qua phpinfo
php -r "phpinfo();" | grep -A2 redis

# Với PHP-FPM, kiểm tra log process
sudo journalctl -u php8.1-fpm -n 50 --no-pager

Nếu bạn đang chạy nhiều phiên bản PHP hoặc nhiều SAPI (CLI + FPM + Apache mod_php), mỗi cái có php.ini riêng — hãy sửa tất cả, không chỉ cái bạn tìm thấy đầu tiên.

Tham Khảo Nhanh — Tên Package Extension Phổ Biến

# Ubuntu/Debian (thay 8.1 bằng phiên bản của bạn)
php8.1-mysql      # mysqli, pdo_mysql
php8.1-pgsql      # pdo_pgsql
php8.1-redis      # redis
php8.1-memcached  # memcached
php8.1-gd         # xử lý ảnh
php8.1-zip        # zip
php8.1-xml        # xml, simplexml, dom
php8.1-mbstring   # chuỗi đa byte
php8.1-curl       # curl
php8.1-intl       # quốc tế hóa
php8.1-soap       # SOAP client

Phòng Ngừa

Trước khi nâng cấp PHP, hãy dump danh sách các extension đã cài để có thể cài lại tất cả chỉ trong một lần:

# Trước khi nâng cấp
php -m > php-extensions-before.txt

# Sau khi nâng cấp, so sánh để thấy những gì còn thiếu
php -m > php-extensions-after.txt
diff php-extensions-before.txt php-extensions-after.txt

Về việc giữ gìn file cấu hình, việc dọn dẹp gọn gàng php.ini và các file trong conf.d/ quan trọng hơn bạn nghĩ. Nếu cấu hình deploy của bạn được lưu dạng YAML (biến Ansible, giá trị Helm, v.v.), công cụ YAML ↔ JSON Converter trên ToolCraft rất tiện để phát hiện cấu hình bị lỗi trước khi đưa lên server — chạy hoàn toàn trên trình duyệt, không upload dữ liệu.

Cũng nên cân nhắc ghim phiên bản các package extension trong script deploy để tránh bị mất extension sau mỗi lần nâng cấp:

# Trong provisioning script / Dockerfile của bạn
apt-get install -y \
  php${PHP_VERSION}-mysql \
  php${PHP_VERSION}-redis \
  php${PHP_VERSION}-gd \
  php${PHP_VERSION}-mbstring

Related Error Notes