Ошибка 'Unable to load dynamic library' в PHP: способы исправления

Раздел: Ошибки и исключения в PHP -> Ошибки PHP

Основные причины ошибки и их устранение

Ошибка "PHP Warning: PHP Startup: Unable to load dynamic library" возникает при запуске PHP, когда интерпретатор не может найти или загрузить указанное расширение. Типичные причины: отсутствие файла библиотеки (dll/so), неправильный путь в директиве extension_dir, несоответствие версий PHP и расширения, конфликты с другими расширениями или отсутствие системных зависимостей. Рассмотрим последовательность действий для диагностики и исправления.

Как проверить и настроить путь к библиотеке в php.ini?

Первый шаг – убедиться, что директива extension_dir указывает на правильный каталог, где находятся расширения. Найдите файл php.ini (обычно в /etc/php/версия/cli/php.ini или в папке с PHP). Выполните команду:

php -i | grep "extension_dir"

Unexpected variable php (неожиданная переменная в php)

Вывод покажет текущий путь. Если он отсутствует или неверен, задайте его явно:

extension_dir = "/usr/lib/php/20200930"

Php warning include failed opening (предупреждение: не удалось открыть include в php)

После этого убедитесь, что файл расширения (например, myextension.so) существует в указанной директории. Проверка:

ls /usr/lib/php/20200930/myextension.so

Php unable to load dynamic library (ошибка загрузки динамической библиотеки в php)

Если файла нет, требуется его установка или компиляция. Также проверьте права доступа – PHP должен иметь право на чтение.

Возможные проблемы:

  • Версия расширения не совпадает с версией PHP (например, built для PHP 7.4, а используется 8.2). В этом случае файл загружается, но вызывает ошибку. Рекомендуется переустановить расширение под текущую версию.
  • Путь extension_dir может быть пустым – тогда PHP ищет библиотеки в текущем каталоге. Лучше указать абсолютный путь.
  • Наличие пробелов или специальных символов в пути.

Как установить расширение PHP через системный менеджер пакетов?

Для распространенных расширений (mysqli, pdo, gd) проще всего использовать менеджер пакетов ОС. Например, для Ubuntu/Debian:

sudo apt update && sudo apt install php-mysqli php-gd

Undefined variable php (неопределенная переменная в php)

Для CentOS/RHEL:

sudo yum install php-mysqli php-gd

Для macOS (Homebrew):

brew install php@8.2-mysqli

После установки расширения обычно автоматически добавляются в php.ini. Если нет, добавьте строку вручную:

extension=mysqli.so

Проверьте подключение через php -m | grep mysqli.

Возможные проблемы:

  • Пакет может быть несовместим с версией PHP – возникает ошибка загрузки. Используйте точное указание версии, например php8.2-mysqli.
  • После установки не обновился php.ini – проверьте наличие директивы extension в файлах конфигурации (обычно /etc/php/версия/cli/conf.d/ или /etc/php/версия/apache2/conf.d/).

Как собрать расширение из исходного кода с помощью phpize?

Если расширение недоступно в репозиториях, его можно скомпилировать. Для этого потребуются исходный код PHP и инструменты сборки. Установите php-dev и php-pear:

sudo apt install php-dev php-pear

Скачайте исходники расширения (например, xdebug), распакуйте, перейдите в каталог и выполните:

phpize
./configure
make -j4
sudo make install

После установки файл .so появится в extension_dir. Добавьте в php.ini:

zend_extension=xdebug.so

Проверьте загрузку: php -v.

Возможные проблемы:

  • Отсутствие зависимостей (libssl, libcurl и т.д.) – компиляция завершится с ошибкой. Установите соответствующие dev-пакеты.
  • Несовместимость API – расширение собрано для другой серии PHP. Проверьте номер API с помощью php -i | grep "PHP API". Расширение должно быть скомпилировано с тем же номером.
  • Права на запись в extension_dir – сборка может поместить файл в недоступное место, исправьте права или используйте sudo.

Как выбрать версию расширения, соответствующую сборке PHP?

PHP распространяется в нескольких конфигурациях: Thread Safety (ts) и Non-Thread Safety (nts), 32-битная или 64-битная, отладка (debug) и релиз. Расширение должно быть собрано под ту же конфигурацию. Определите параметры вашего PHP:

php -i | grep -E "Thread Safety|Architecture|Debug Build"

Результат:

Thread Safety => enabled (или disabled)
Architecture => x64
PHP API => 20200930

Скачивайте и устанавливайте расширение, соответствующее этой строке. Например, для Windows DLL обычно имеют маркировку: php_xdebug-3.3.1-8.2-ts-vs16-x64.dll.

Возможные проблемы:

  • Использование NTS-расширения в TS-сборке PHP приводит к ошибке загрузки. Всегда внимательно читайте документацию.
  • Разрядность: 32-битное расширение не загрузится в 64-битном PHP.

Какие расширения могут конфликтовать и как их временно отключить?

Иногда два расширения требуют одну и ту же библиотеку разных версий. Для диагностики отключите все необязательные расширения, оставив только проблемное. Переименуйте файлы конфигурации в /etc/php/version/conf.d/ (например, mv 20-mysqli.ini 20-mysqli.ini.bak). Проверьте загрузку:

php -v

Если ошибка исчезла, включайте расширения по одному, чтобы найти конфликт.

Возможные проблемы:

  • После отключения расширения может перестать работать часть функционала сайта. Для тестирования используйте изолированное окружение.
  • Конфликт может быть между системной библиотекой и расширением – тогда поможет только перекомпиляция с другими флагами.

Где искать более подробную информацию об ошибке загрузки?

PHP выводит только краткое предупреждение. Чтобы получить больше деталей, включите отображение ошибок в php.ini:

display_errors = On
error_reporting = E_ALL

Также смотрите системные логи. Для Linux:

tail -f /var/log/apache2/error.log

или

journalctl -u php-fpm -n 50

Windows: Event Viewer и логи PHP (если настроены).

Возможные проблемы:

  • Логи могут быть не настроены. В php.ini укажите error_log=/var/log/php_errors.log.
  • Иногда ошибка скрыта в логах веб-сервера, а не PHP.

Как помочь PHP найти системные зависимости расширения?

Многие расширения зависят от внешних библиотек (.so в Linux, .dll в Windows). Если библиотека находится в нестандартном месте, укажите путь к ней через переменные окружения. В Linux добавьте путь в LD_LIBRARY_PATH:

export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
php -v

Или задайте в конфигурации PHP через dl() (но не рекомендуется). Лучше слинковать библиотеку в стандартный каталог /usr/lib. Для Windows можно добавить каталог в PATH.

Возможные проблемы:

  • Переменная LD_LIBRARY_PATH может быть переопределена в безопасном режиме. Используйте ldconfig для обновления кэша.
  • Наличие нескольких версий одной библиотеки – может загрузиться не та.

Подробные примеры и их результаты

Ниже приведены расширенные сценарии, иллюстрирующие диагностику и исправление ошибки загрузки динамических библиотек PHP.

Пример 1: Проверка и настройка extension_dir

Выполнить команду для определения текущего каталога расширений:

Пример
php -i | grep extension_dir

Возможный вывод:

extension_dir => /usr/lib/php/20200930 => /usr/lib/php/20200930

Проверить наличие файла расширения, например, mysqli.so:

Пример
ls -la /usr/lib/php/20200930/mysqli.so

Если файл отсутствует, вывод будет:

ls: cannot access '/usr/lib/php/20200930/mysqli.so': No such file or directory

Тогда установите пакет или скопируйте правильную версию в этот каталог.

Пример 2: Установка расширения через apt с указанием версии PHP

Предположим, используется PHP 8.2. Установить модуль pdo_mysql:

Пример
sudo apt install php8.2-mysql

После установки проверить, появился ли файл конфигурации:

Пример
ls /etc/php/8.2/cli/conf.d/ | grep mysql

Результат:

20-mysqli.ini
20-pdo_mysql.ini

Убедиться, что расширения загружаются:

Пример
php -m | grep -i mysql

Вывод:

mysqli
pdo_mysql

Пример 3: Компиляция простого расширения "hello"

Создадим минимальное расширение на C. Исходный код (файл hello.c):

Пример
#include <php.h>
#include <ext/standard/info.h>

PHP_FUNCTION(hello_world) {
    php_printf("Hello, World!\n");
}

const zend_function_entry hello_functions[] = {
    PHP_FE(hello_world, NULL)
    PHP_FE_END
};

zend_module_entry hello_module_entry = {
    STANDARD_MODULE_HEADER,
    "hello",
    hello_functions,
    NULL,
    NULL,
    NULL,
    NULL,
    PHP_MINFO(hello),
    PHP_HELLO_VERSION,
    STANDARD_MODULE_PROPERTIES
};

#ifdef COMPILE_DL_HELLO
    ZEND_GET_MODULE(hello)
#endif

Создайте файл config.m4:

Пример
PHP_ARG_ENABLE(hello, whether to enable hello, [ --enable-hello Enable hello support])

if test "$PHP_HELLO" != "no"; then
    PHP_NEW_EXTENSION(hello, hello.c, $ext_shared)
fi

Выполните:

Пример
phpize
./configure --enable-hello
make -j4
sudo make install

Результат make install поместит hello.so в extension_dir. Добавьте в php.ini:

Пример
extension=hello.so

Проверка:

Пример
php -r 'hello_world();'

Ожидаемый вывод:

Hello, World!

Пример 4: Проверка и выбор Thread Safety для Windows

На Windows PHP имеет две версии. Определите текущую:

Пример
php -i | findstr "Thread Safety"

Вывод:

Thread Safety => enabled

Скачайте расширение xdebug для PHP 8.2 TS x64. Пусть файл называется php_xdebug-3.3.1-8.2-ts-vs16-x64.dll. Скопируйте его в ext (обычно C:\php\ext). Добавьте в php.ini:

Пример
zend_extension=C:\php\ext\php_xdebug-3.3.1-8.2-ts-vs16-x64.dll

Проверьте загрузку:

Пример
php -v

Если версия несовместима, появится предупреждение об ошибке загрузки. В таком случае загрузите NTS-версию, если PHP без Thread Safety.

Пример 5: Отключение расширений для поиска конфликта

Предположим, после установки imagick возникает ошибка. Временно отключите все расширения, кроме core:

Пример
cd /etc/php/8.2/cli/conf.d/
sudo mkdir backup && sudo mv *.ini backup/

Затем включите только imagick:

Пример
sudo cp backup/20-imagick.ini .

Проверьте загрузку:

Пример
php -v

Если ошибка исчезла, конфликт с другим расширением. Включайте по одному.

Пример 6: Использование ldd для проверки зависимостей расширения

В Linux, если расширение загружается с ошибкой "undefined symbol", проверьте его зависимости:

Пример
ldd /usr/lib/php/20200930/imagick.so

Возможный вывод:

linux-vdso.so.1 (0x00007fffc4d5c000)
libMagickWand-7.Q16HDRI.so.7 => not found
libMagickCore-7.Q16HDRI.so.7 => /usr/lib/x86_64-linux-gnu/libMagickCore-7.Q16HDRI.so.7 (0x00007f...)

Если какая-то библиотека не найдена (not found), установите соответствующую версию (например, libmagickwand-dev).

Ошибка загрузки динамической библиотеки в PHP - comments

En
Php unable to load dynamic library (php)