Устранение неполадок с драйверами Microsoft для PHP для SQL Server

Скачать драйвер PHP

Диагностируйте и решайте распространённые проблемы при использовании Microsoft Drivers for PHP for SQL Server для подключения к SQL Server, База данных SQL Azure, Управляемый экземпляр SQL Azure и SQL Database Microsoft Fabric.

Для общих шаблонов обработки ошибок и предупреждений см. раздел «Обработка ошибок и предупреждений». Для сбора диагностических данных на стороне драйвера см. Logging activity.

Проблемы с установкой

Расширение не загружено

Симптомы

  • phpinfo() не содержит раздела sqlsrv или pdo_sqlsrv.
  • PDOException: could not find driver при создании PDO с помощью DSN sqlsrv:.
  • Fatal error: Uncaught Error: Call to undefined function sqlsrv_connect().

Возможные причины и решения:

  • Расширение не включено в php.ini. Проверьте, что оба extension=sqlsrv и extension=pdo_sqlsrv не имеют комментариев. В Windows используйте полное имя файла (extension=php_sqlsrv_84_ts_x64.dll). Подробности смотрите в разделе «Загрузка драйверов».
  • Неправильная сборка безопасности резьбы. Двоичный файл драйвера должен соответствовать параметру потокобезопасности вашей сборки PHP (ts для потокобезопасной, nts для непотокобезопасной). Запустите команду php -i | grep "Thread Safety", чтобы проверить. Скачайте совпадающий бинарный файл со страницы скачивания.
  • Драйвер Microsoft ODBC отсутствует. Драйверы PHP обертывают драйвер Microsoft ODBC для SQL Server. На Linux и macOS установите msodbcsql18 (или msodbcsql17) через менеджер пакетов перед загрузкой расширений. В Windows установите драйвер ODBC со страницы загрузки.

Проверьте успешную установку:

php -m | grep -i sqlsrv

Вы должны увидеть в выводе и pdo_sqlsrv, и sqlsrv.

Установка PECL не удаётся на Linux или macOS

Симптомы

error: ‘SQL_HANDLE_DBC’ undeclared (first use in this function)
fatal error: 'sql.h' file not found

Исправление:

Установите файлы заголовков для разработки ODBC перед запуском pecl install:

  • Ubuntu и Debian: sudo apt-get install unixodbc-dev
  • Red Hat, Fedora и CentOS: sudo dnf install unixODBC-devel
  • Альпийские: apk add unixodbc-dev
  • macOS:brew install unixodbc

Потом попробуйте снова:

sudo pecl install sqlsrv
sudo pecl install pdo_sqlsrv

Если pecl после установки заголовков всё равно не получится, цепочка инструментов сборки может быть неполной. Установите phpize, re2c, и компилятор на C++ (build-essential на Debian и Ubuntu, gcc-c++ make на Red Hat и Fedora, build-base на Alpine).

Полный путь установки смотрите в разделе «Инструкция по установке для Linux и macOS».

Установлено несколько версий PHP

Симптомы

phpinfo() на вашем веб-сервере отображается одна версия PHP, но php -v в командной строке — другая, и драйвер загружен только в одной из них.

Исправление:

У каждой версии PHP есть свои каталоги php.ini и ext. Найдите правильный конфигурационный файл php --ini внутри среды, где отсутствует драйвер, и добавьте туда линии extension= . Перезапустите веб-сервер (Apache, Nginx + PHP-FPM или IIS) после любых изменений php.ini.

Проблемы с подключением

Не удаётся подключиться к серверу

Симптомы

SQLSTATE[08001]: [Microsoft][ODBC Driver 18 for SQL Server]TCP Provider: A connection attempt failed
SQLSTATE[HYT00]: [Microsoft][ODBC Driver 18 for SQL Server]Login timeout expired

Возможные причины и решения:

  • Сервер недоступен. Проверьте, правильно ли указано имя сервера и порт. На PHP-хосте проверьте наличие прямого TCP-соединения.

    # Linux and macOS
    nc -vz <server>.database.windows.net 1433
    
    # Windows PowerShell
    Test-NetConnection -ComputerName <server>.database.windows.net -Port 1433
    
  • Брандмауэр блокирует исходящий трафик через порт 1433. Корпоративные межсетевые экраны и облачные NSG часто блокируют исходящий порт 1433. Добавьте исключение или разрешите IP-диапазоны База данных SQL Azure для вашего региона.

  • Azure SQL server firewall. Добавьте публичный IP вашего клиента в правила серверного межсетевого экрана в портале Azure.

  • Именованный экземпляр. Для именованного экземпляра убедитесь, что сервис SQL Server Browser работает на сервере и что UDP 1434 открыт. Или подключайтесь по порту, а не по имени экземпляра.

Сбой входа

Симптомы

SQLSTATE[28000]: [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Login failed for user '<user_id>'.

Возможные причины и решения:

  • Режим аутентификации SQL отключен. Локальные экземпляры SQL Server по умолчанию используют только аутентификацию Windows. Включите аутентификацию в смешанном режиме в SQL Server Management Studio в разделе «Безопасность свойств> сервера», а затем перезапустите сервис SQL Server.
  • Azure SQL credentials format. Azure SQL требует полностью квалифицированное имя пользователя (user@servername) при подключении из инструментов, которые не добавляют его автоматически.
  • Пользователь не сопоставлен с базой данных. Проверьте, что логин имеет пользовательское отображение в целевой базе данных и что у пользователя есть необходимые права.
  • Предпочитаю Microsoft Entra ID. Для Azure SQL, Управляемый экземпляр SQL Azure и SQL Database in Fabric используйте аутентификацию Microsoft Entra (Authentication=ActiveDirectoryMsi, Authentication=ActiveDirectoryServicePrincipal, или токен доступа) вместо входов в SQL. См. статью "Подключение с помощью проверки подлинности Microsoft Entra".

Недопустимое значение, указанное для атрибута строка подключения 'Authentication'

Симптомы

SQLSTATE[08001]: [Microsoft][ODBC Driver 17 for SQL Server]Invalid value specified for connection string attribute 'Authentication'

Причина.

Драйвер ODBC сообщает об ошибке, но настоящая проблема в том, к какому драйверу PDO_SQLSRV привязан. Если в DSN нет Driver= ключевого слова, а на хосте установлены и ODBC 17, и ODBC 18, PDO_SQLSRV можно привязать к старой версии. Старые сборки ODBC 17.x не знают новых Authentication значений, таких как ActiveDirectoryServicePrincipal или ActiveDirectoryDefault, и даже ActiveDirectoryMsi требуют ODBC 17.3.1.1 или более поздних версий.

Исправление:

Закрепите драйвер в DSN:

<?php
$dsn = "sqlsrv:Driver={ODBC Driver 18 for SQL Server};Server=$server;Database=$db;" .
       "Encrypt=true;Authentication=ActiveDirectoryMsi";
$conn = new PDO($dsn, null, null, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);

Форма в скобках ({ODBC Driver 18 for SQL Server}) избегает пробелов в названии драйвера. Само сообщение об ошибке всегда содержит имя драйвера, который её сгенерировал, поэтому префикс [Microsoft][ODBC Driver 17 for SQL Server] в сообщении об ошибке — самый быстрый способ подтвердить, что был привязан не тот драйвер.

Недопустимое ключевое слово 'UID' было указано в строке DSN

Симптомы

SQLSTATE[IMSSP]: An invalid keyword 'UID' was specified in the DSN string.

Причина.

PDO_SQLSRV допускает только ключевые слова DSN из списка разрешённых и не принимает UID или PWD в строке DSN. PDO резервирует для них второй и третий аргументы конструктора, а PDO_SQLSRV внутренне преобразует их в ODBC UID/PWD.

Исправление:

Переместите имя пользователя (и пароль для SQL-аутентификации) в конструктор PDO:

<?php
// SQL authentication.
$dsn = "sqlsrv:Driver={ODBC Driver 18 for SQL Server};Server=$server;Database=$db;Encrypt=true";
$conn = new PDO($dsn, $user, $password);

// User-assigned managed identity. Pass the identity's client ID as $username.
$dsn = "sqlsrv:Driver={ODBC Driver 18 for SQL Server};Server=$server;Database=$db;" .
       "Encrypt=true;Authentication=ActiveDirectoryMsi";
$conn = new PDO($dsn, $clientId, null);

Процедурный драйвер SQLSRV, напротив, принимает UID и PWD в массиве параметров подключения, передаваемом в sqlsrv_connect().

PDO_SQLSRV молча игнорирует AccessToken в массиве опций

Симптом:

У вас есть токен доступа Microsoft Entra (например, из az account get-access-token --resource https://database.windows.net/, ManagedIdentityCredential или ClientSecretCredential), и вы передаёте его в PDO_SQLSRV в качестве ['AccessToken' => $token] в четвёртом аргументе конструктора. Попытка подключения завершается с непонятной ошибкой, например Windows logins are not supported in this version of SQL Server или Login failed for user '', как будто учетные данные не были указаны.

Причина.

Четвёртый конструкторный аргумент PDO зарезервирован для драйвер-специфичных атрибутных констант (целочисленных ключей, таких как PDO::ATTR_ERRMODE). PDO молча отбрасывает элементы со строковыми ключами, такие как AccessToken, поэтому PDO_SQLSRV никогда не видит этот токен. Затем соединение возвращается к интегрированной аутентификации Windows, которую сервер отклоняет.

Исправление:

Переместите AccessToken в строку DSN. Зарезервируйте массив опционов для PDO::ATTR_* констант.

<?php
$server = '<server>.database.windows.net';
$token  = getenv('SQL_ACCESS_TOKEN');   // raw JWT, no "Bearer " prefix

$dsn = "sqlsrv:Server=$server;Database=<database>;Encrypt=true;AccessToken=$token";
$conn = new PDO($dsn, null, null, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);

Для дополнительных примеров Microsoft Entra аутентификации, включая форму DSN для PDO_SQLSRV, см. раздел Connect using Microsoft Entra authentication.

При использовании процедурного SQLSRV AccessToken следует помещать в массив connection-info, передаваемый в sqlsrv_connect(), которая сама оборачивает необработанный JWT в SQL_COPT_SS_ACCESS_TOKEN:

<?php
$server = '<server>.database.windows.net';
$token  = getenv('SQL_ACCESS_TOKEN');   // raw JWT, no "Bearer " prefix

$connectionInfo = [
    'Database'               => '<database>',
    'AccessToken'            => $token,
    'Encrypt'                => true,
    'TrustServerCertificate' => false,
    'Driver'                 => '{ODBC Driver 18 for SQL Server}',
];

$conn = sqlsrv_connect($server, $connectionInfo);
if ($conn === false) {
    print_r(sqlsrv_errors());
    exit(1);
}

Ошибки в сертификатах TLS

Симптомы

SQLSTATE[08001]: SSL Provider: The certificate chain was issued by an authority that is not trusted
SQLSTATE[08001]: SSL Provider: The target principal name is incorrect

Решения:

Предпочитайте проверенный сертификат. Используйте TrustServerCertificate=true только для локальной разработки при работе с сервером, который вы контролируете.

Для разработки на основе самоподписанного сертификата:

<?php
$server   = 'localhost';
$database = '<database>';
$user     = '<user_id>';
$password = '<password>';

$dsn = "sqlsrv:Server=$server;Database=$database;Encrypt=true;TrustServerCertificate=true";
$conn = new PDO($dsn, $user, $password, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);

Предостережение

TrustServerCertificate=true Отключает проверку сертификатов сервера. Никогда не переносите этот сеттинг в производство, сценографию или общую среду.

Если имя хоста в рабочей среде не совпадает с общим именем (Common Name) сертификата (например, при подключении через слушатель), укажите фактическое имя субъекта сертификата:

<?php
$dsn = "sqlsrv:Server=<listener>;Database=<database>;Encrypt=true;HostNameInCertificate=*.database.windows.net;Authentication=ActiveDirectoryMsi";
$conn = new PDO($dsn, null, null, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);

Время соединения истекло

Симптомы

SQLSTATE[HYT00]: Login timeout expired

Возможные причины и решения:

  • LoginTimeout не задано или задано слишком низкое значение для холодного переключения при отказе. Установите в DSN явное значение LoginTimeout (в секундах) при подключении к Azure SQL. Резервные переключения на группу отказов и холодный запуск баз данных могут занимать больше времени, чем позволяет короткий тайм-аут на стороне клиента. Смотрите опции подключения для ссылки на опцию.
  • Бюджет переподключения в режиме простоя усечён. Если вы установите ConnectRetryCount и ConnectRetryInterval, убедитесь, что LoginTimeout >= ConnectRetryCount * ConnectRetryInterval. В противном случае тайм-аут входа заканчивает цикл переподключения раньше времени. См. устойчивость неактивного подключения.
<?php
$dsn = "sqlsrv:Driver={ODBC Driver 18 for SQL Server};Server=<server>.database.windows.net;Database=<database>;" .
       "Encrypt=true;LoginTimeout=90;ConnectRetryCount=5;ConnectRetryInterval=15;" .
       "Authentication=ActiveDirectoryMsi";
$conn = new PDO($dsn, null, null, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);

Задачи выполнения запросов

Тихие сбои в PDO

Симптом:

Вызов PDO::exec() или PDOStatement::execute() возвращает false, но не вызывает исключение.

Исправление:

В версиях PHP 8.0 и более поздних по умолчанию режим ошибки PDO — PDO::ERRMODE_EXCEPTION. Если вызов возвращается false без броска, приложение меняет режим на PDO::ERRMODE_SILENT или PDO::ERRMODE_WARNING. Переведите его обратно в режим исключений, чтобы при ошибках выбрасывались исключения:

<?php
$conn = new PDO($dsn, $user, $password, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);

Если нельзя глобально изменить режим, проверяйте $conn->errorInfo() (или $stmt->errorInfo()) после каждого звонка. Массив содержит [SQLSTATE, driver code, driver message].

Недопустимое имя объекта

Симптомы

SQLSTATE[42S02]: [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Invalid object name 'Products'.

Возможные причины и решения:

  • Неправильный контекст базы данных. Проверьте быстрым запросом:

    <?php
    $stmt = $conn->query("SELECT DB_NAME()");
    echo $stmt->fetchColumn();
    
  • Отсутствует квалификатор схемы. Используйте полностью квалифицированные имена, чтобы избежать зависимости от стандартной схемы звонящего:

    SELECT * FROM dbo.Products;
    
  • Чувствительность к регистру. Базы данных, созданные с коллацией, учитывающей регистр, считают products и Products разными объектами. Совпадение с точным случаем в определении таблицы.

Неправильное количество параметров

Симптомы

SQLSTATE[HY093]: Invalid parameter number
SQLSTATE[07002]: COUNT field incorrect or syntax error

Исправление:

Для PDO_SQLSRV количество заполнителей ? должно совпадать с количеством значений, которые вы передаёте в execute(), и каждый ? связывает одно скалярное значение (а не массив). Для именованных параметров каждый :name в SQL-запросе должен присутствовать в массиве, и наоборот.

<?php
$stmt = $conn->prepare(
    "SELECT * FROM dbo.Products WHERE CategoryID = ? AND ListPrice > ?"
);
$stmt->execute([1, 50.0]);
foreach ($stmt as $row) {
    // ...
}

Для SQLSRV передайте массив параметров в sqlsrv_query() или sqlsrv_prepare():

<?php
$stmt = sqlsrv_query(
    $conn,
    "SELECT * FROM dbo.Products WHERE CategoryID = ? AND ListPrice > ?",
    [1, 50.0]
);
if ($stmt === false) {
    die(print_r(sqlsrv_errors(), true));
}

Для более широкого введения в связывание параметров см. раздел «Выполнить параметризованные запросы».

Эмулируемые подготовленные запросы PDO маскируют ошибки

Симптомы

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

Причина.

PDO_SQLSRV поддерживает как эмулируемые, так и собственные подготовленные выражения. Эмуляция подготовленных выражений (PDO::ATTR_EMULATE_PREPARES = true) подставляет параметры на стороне клиента. Native подготавливает (false) отправку запроса и параметров на сервер по отдельности. Поведение отличается для TOP (?), параметров с таблицными значениями и некоторых крайних случаев в типовом принуждении.

Исправление:

Предпочитаю местные продукты в производстве. Установите PDO::ATTR_EMULATE_PREPARES => false во время подключения, чтобы поведение было одинаковым во всех средах:

<?php
$conn = new PDO($dsn, null, null, [
    PDO::ATTR_ERRMODE          => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => false,
]);

Для подробностей о том, когда использовать каждый режим, см. PDO::prepare.

Задачи с типами данных

Символы Юникода появляются как ? или искажаются

Симптомы

Строки, записываемые PHP, содержат знаки вопроса или символы замены вместо исходных не-ASCII-символов. При чтении возвращается искажённый текст.

Возможные причины и решения:

  • Тип столбца — VARCHAR, а не NVARCHAR. Столбцы varchar используют кодовую страницу, а не Unicode. Используйте nvarchar для интернационализированного текста.

  • Отсутствует подсказка по кодированию UTF-8 на PDO_SQLSRV. Если ваш столбец SQL Server — nvarchar, а данные PHP — UTF-8, скажите драйверу конвертировать между UTF-8 (клиент) и UTF-16 (сервер):

    <?php
    $conn = new PDO(
        "sqlsrv:Server=<server>;Database=<database>;Encrypt=true",
        $user,
        $password,
        [
            PDO::ATTR_ERRMODE                    => PDO::ERRMODE_EXCEPTION,
            PDO::SQLSRV_ATTR_ENCODING            => PDO::SQLSRV_ENCODING_UTF8,
        ]
    );
    
  • Драйвер SQLSRV: явно запрашивать UTF-8. SQLSRV_ENC_CHAR является стандартной 8-битной системной кодовой страницей, а не UTF-8. Для UTF-8 с SQLSRV установите "CharacterSet" => "UTF-8" на соединении и передайте литерал 'UTF-8' в SQLSRV_PHPTYPE_STRING при извлечении или привязке. См. Отправка и получение данных UTF-8.

Ошибки конвертации времени и даты

Симптомы

SQLSTATE[22007]: Invalid character value for cast specification

Исправление:

В PDO_SQLSRV не связывайте сырой DateTime предмет. PDO преобразует привязанные значения в строки перед привязкой, а у PHP нет метода __toString() в DateTime, поэтому execute([new DateTime(...)]) вызывает Object of class DateTime could not be converted to string. Сначала отформатируйте значение или передайте строку ISO 8601 (YYYY-MM-DD HH:MM:SS[.fff]), а не строку с локальным форматом.

<?php
$stmt = $conn->prepare("INSERT INTO dbo.Events (EventDate) VALUES (?)");
$stmt->execute([(new DateTime("2026-03-15 10:00:00"))->format("Y-m-d H:i:s.u")]);

Чтобы получать столбцы datetime в виде объектов DateTime, а не строк в PDO_SQLSRV, установите атрибут выражения:

<?php
$stmt = $conn->prepare("SELECT EventDate FROM dbo.Events");
$stmt->setAttribute(PDO::SQLSRV_ATTR_FETCHES_DATETIME_TYPE, true);
$stmt->execute();

Подробнее см. Retrieve datetime objects (PDO_SQLSRV).

Задачи с десятичным форматированием

Симптомы

У значений в диапазоне от -1 до 1 отсутствует ведущий ноль, или значения типов money и smallmoney отображают неожиданное количество знаков после запятой.

Исправление:

PDO_SQLSRV всегда получает десятичные и числовые значения в виде строк с их точной точностью и масштабом. Установите для PDO::SQLSRV_ATTR_FORMAT_DECIMALS значение, при котором к значениям в диапазоне от -1 до 1 добавляется ведущий ноль:

<?php
$conn->setAttribute(PDO::SQLSRV_ATTR_FORMAT_DECIMALS, true);

PDO::SQLSRV_ATTR_DECIMAL_PLACES относится только к значениям money и smallmoney. Он устанавливает отображаемую шкалу от 0 до 4 и может округлять отображаемое значение. Это не влияет на десятичные или числовые значения.

Для подробностей см. Форматирование десятичных знаков и денег (PDO_SQLSRV) или Форматирование десятичных знаков и денег (SQLSRV).

Проблемы с транзакциями

Изменения данных не сохраняются

Симптомы

Строки, которые вы вставляете или обновляете в PHP, не появляются при запросе из другой сессии.

Причина.

PDO::beginTransaction() открывает явную транзакцию, требующую явного commit(). Если PHP-скрипт заканчивается без вызова commit(), PDO возвращает транзакцию назад во время очистки соединения.

Исправление:

Всегда сочетайте beginTransaction() с commit(), и используйте try/catch для отката при ошибке:

<?php
try {
    $conn->beginTransaction();
    $conn->exec("INSERT INTO dbo.Orders (CustomerID, Total) VALUES (1, 100)");
    $conn->exec("UPDATE dbo.Inventory SET Stock = Stock - 1 WHERE ProductID = 5");
    $conn->commit();
} catch (PDOException $e) {
    $conn->rollBack();
    throw $e;
}

Для SQLSRV используйте sqlsrv_begin_transaction, sqlsrv_commit, и sqlsrv_rollback.

Ошибки взаимоблокировки

Симптомы

SQLSTATE[40001]: [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Transaction (Process ID 62) was deadlocked

Исправление:

Обрабатывайте ошибки временной взаимоблокировки с помощью механизма повторных попыток. Оберните всю транзакцию (а не только инструкцию, на которой произошёл сбой), чтобы предыдущие инструкции повторно выполнялись в новой транзакции. Пример шаблона повторных попыток, подходящего для использования в рабочей среде, см. на странице драйвера PHP.

Повторяющиеся тупики указывают на конструктивную проблему. Получите граф взаимоблокировки и проанализируйте, какие инструкции и типы блокировок в ней задействованы. Распространённые исправления включают операции перепорядка так, чтобы конкурирующие транзакции получали блокировки в той же последовательности, сокращение объёма транзакций и добавление индексов для сокращения длительности блокировки. Полный обзор смотрите руководство по Deadlocks.

Проблемы устойчивости соединения

Повторное подключение не происходит

Симптомы

Неактивное соединение остаётся разорванным после переключения База данных SQL Azure на резервный сервер, даже если вы установили ConnectRetryCount и ConnectRetryInterval.

Возможные причины и решения:

  • Активный курсор на стороне сервера. Функция восстановления неактивных подключений повторно подключает только неактивные подключения. Открытый серверный курсор или ожидающая транзакция поддерживают соединение активным. Освободите серверные курсоры, используя sqlsrv_free_stmt() или $stmt = null; (PDO) перед окном резервирования, либо переключитесь на клиентский буферизованный курсор. См. устойчивость неактивного подключения.
  • Состояние сессии, не восстанавливаемое. Некоторые элементы состояния сеанса не удаётся восстановить, включая временные таблицы, глобальные и локальные курсоры, контекст транзакции, блокировки приложения, EXECUTE AS/REVERT, дескрипторы автоматизации OLE, подготовленные дескрипторы XML и флаги трассировки. Любое из этих состояний сессии предотвращает автоматическое повторное подключение.
  • LoginTimeout Слишком маленький. Если ConnectRetryCount * ConnectRetryInterval > LoginTimeout, драйвер прекращает повторные попытки при достижении LoginTimeout. Увеличьте LoginTimeout, чтобы покрыть весь бюджет повторных попыток.

Проблемы с производительностью

Для диагностики и устранения медленных запросов, холодных запусков, больших наборов результатов и массовых вставок см. раздел Настройка производительности.

Включить диагностику драйверов

Если вызовы на уровне error_log() приложений не дают достаточно информации, включите логирование со стороны водителя. Он отражает каждый вызов водителя по ODBC.

PDO_SQLSRV

Установите pdo_sqlsrv.log_severity в php.ini и перезапустите веб-сервер. Эта настройка читается только при инициализации:

[pdo_sqlsrv]
pdo_sqlsrv.log_severity = 1

Значения: 0 (выключено, по умолчанию), -1 (ошибки, предупреждения и уведомления), 1 (ошибки), 2 (предупреждения) и 4 (уведомления).

SQLSRV

Включите логирование во время выполнения с помощью sqlsrv_configure():

<?php
sqlsrv_configure("LogSubsystems", SQLSRV_LOG_SYSTEM_CONN | SQLSRV_LOG_SYSTEM_STMT);
sqlsrv_configure("LogSeverity", SQLSRV_LOG_SEVERITY_ERROR | SQLSRV_LOG_SEVERITY_WARNING);

Записи журнала записываются в файл, заданный с помощью error_log в php.ini. Полный список подсистем и степеней серьёзности см. раздел «Логирование активности».

Проблемы с контейнерами и CI

Отсутствующие системные библиотеки в Linux

Симптомы

error while loading shared libraries: libodbc.so.2: cannot open shared object file
error while loading shared libraries: libssl.so.1.1: cannot open shared object file

Исправление:

Установите зависимости среды выполнения перед установкой драйвера PHP:

Распространение Команда установки
Ubuntu и Debian sudo apt-get install unixodbc libgssapi-krb5-2
Red Hat и Fedora sudo dnf install unixODBC krb5-libs
Алпайн apk add unixodbc gcompat

Затем установите msodbcsql18 из репозитория пакетов Microsoft. О репозиториях пакетов и версиях для конкретных дистрибутивов см. руководство по установке драйвера ODBC.

Сборки образов Docker успешно выполняются, но соединения не работают во время выполнения

Симптомы

Образ собирается, PHP запускается, но PDO::__construct() выдаёт ошибку о том, что драйвер ODBC не найден.

Исправление:

Проверьте, что драйвер ODBC установлен в образе выполнения работы, а не только на этапе сборки. Установите msodbcsql18 и unixodbc-dev на том же этапе, который отправляется в продакшен. В многоступенчатой сборке устанавливайте их на финальном этапе. Одноступенчатая установка на базе Debian выглядит так:

# Pin to a specific PHP minor version in production, for example php:8.4.11-cli.
FROM php:8.4-cli
RUN apt-get update && apt-get install -y --no-install-recommends \
        curl gnupg2 apt-transport-https ca-certificates \
    && curl -sSL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /usr/share/keyrings/microsoft.gpg \
    && echo "deb [arch=amd64 signed-by=/usr/share/keyrings/microsoft.gpg] https://packages.microsoft.com/debian/12/prod bookworm main" > /etc/apt/sources.list.d/mssql-release.list \
    && apt-get update \
    && ACCEPT_EULA=Y apt-get install -y --no-install-recommends msodbcsql18 unixodbc-dev \
    # $PHPIZE_DEPS ships in the official php image and includes gcc, make, autoconf, and re2c.
    && apt-get install -y --no-install-recommends $PHPIZE_DEPS \
    && pecl install sqlsrv pdo_sqlsrv \
    && docker-php-ext-enable sqlsrv pdo_sqlsrv \
    && apt-get purge -y --auto-remove $PHPIZE_DEPS \
    && rm -rf /var/lib/apt/lists/*