Обзор драйверов Майкрософт для PHP для SQL Server

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

Драйверы Microsoft для PHP для SQL Server включают два расширения для PHP — SQLSRV и PDO_SQLSRV. PDO_SQLSRV реализует интерфейс PHP Data Objects (PDO). Оба расширения используют драйвер Microsoft ODBC для SQL Server для подключения к Microsoft SQL. Их PHP-API, параметры для драйверов и стандартные типы PHP различаются. Например, SQLSRV по умолчанию возвращает значения даты и времени как DateTime объекты, а PDO_SQLSRV по умолчанию возвращает строки. Для системных требований см. Системные требования к драйверам Microsoft для PHP для SQL Server.

Выберите SQLSRV или PDO_SQLSRV

Если вы... Использовать
Начинаете новый проект, в котором больше нигде не используется код PDO Выберите интерфейс, который ваше приложение будет использовать постоянно. SQLSRV предоставляет процедурные функции и явные дескрипторы параметров. PDO_SQLSRV подходит для кода, организованного вокруг объектов PDO и PDOStatement.
Уже использую PDO с другой базой данных (MySQL, PostgreSQL, SQLite) PDO_SQLSRV, чтобы уровень доступа к данным оставался единым во всех базах данных.
Используйте фреймворк или библиотеку, которая ожидает объект соединения PDO PDO_SQLSRV.
Нужен ручной, пофрагментный контроль над моментом передачи данных потока SQLSRV, с использованием sqlsrv_send_stream_data(). PDO_SQLSRV также потоково передаёт большие значения, связывая ресурс потока PHP с PDO::PARAM_LOB, но весь поток отправляется автоматически во время execute(), а не по блокам, управляемым вызывающим.
Поддерживать приложение, которое уже вызывает функции sqlsrv_* SQLSRV, если только вы не планируете переписывать его код доступа к данным для PDO.

Установите либо расширение, либо оба расширения. Загрузки Windows содержат отдельные бинарные расширения; на Linux и macOS устанавливайте пакеты sqlsrv и pdo_sqlsrv отдельно. Вы можете загрузить оба в одном процессе PHP. SQLSRV возвращает ресурсы соединений и инструкций; PDO_SQLSRV возвращает объекты PDO и PDOStatement. Не передавайте ресурс из одного API в другой.

Использование PDO не делает синтаксис Transact-SQL (T-SQL) переносимым в другую базу данных. PDO предоставляет вам общий PHP-интерфейс; ваши запросы, схема, аутентификация и специфические для драйвера атрибуты всё равно могут по-прежнему быть привязаны к Microsoft SQL. Аналогично, использование процедурного расширения не требует процедурной организации во всём вашем приложении: вы можете вызывать функции SQLSRV из своих классов.

Сравните один и тот же результат в обоих API

Запустите эти программы перед выбором PHP-представления, которое ожидает ваше приложение. Они выбирают одно и то же целое число, дату и SQL NULL, но значения по умолчанию не идентичны. Ни таблицы, ни образец базы данных не требуются.

Установите и загрузите выбранное расширение. Установите SQL_SERVER, SQL_DATABASE, SQL_USER, и SQL_PASSWORD в среде процесса для существующей тестовой базы данных SQL Server. Сертификат сервера должен быть доверенным и соответствовать настроенной конечной точке. Сведения о настройке и беспарольных вариантах Azure см. в разделе «Подключение к серверу».

SQLSRV

Сохраните эту полную программу как compare-sqlsrv.php, и запустите php compare-sqlsrv.php.

<?php
$config = [];
foreach (['SQL_SERVER', 'SQL_DATABASE', 'SQL_USER', 'SQL_PASSWORD'] as $name) {
    $value = getenv($name);
    if ($value === false || $value === '') {
        throw new RuntimeException("Set $name before running this example.");
    }
    $config[$name] = $value;
}
foreach (['SQL_DATABASE', 'SQL_USER', 'SQL_PASSWORD'] as $name) {
    $config[$name] = '{' . str_replace('}', '}}', $config[$name]) . '}';
}
$conn = sqlsrv_connect($config['SQL_SERVER'], [
    'Database' => $config['SQL_DATABASE'],
    'UID' => $config['SQL_USER'],
    'PWD' => $config['SQL_PASSWORD'],
    'Encrypt' => true,
    'TrustServerCertificate' => false,
    'LoginTimeout' => 30,
    'CharacterSet' => 'UTF-8',
]);
if ($conn === false) {
    throw new RuntimeException(print_r(sqlsrv_errors(), true));
}
$stmt = null;
try {
    $stmt = sqlsrv_query($conn, "SELECT CAST(42 AS int) AS CountValue, "
        . "CAST('2026-10-19' AS date) AS DayValue, CAST(NULL AS int) AS Missing");
    if ($stmt === false) {
        throw new RuntimeException(print_r(sqlsrv_errors(), true));
    }
    $row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
    if ($row === false) {
        throw new RuntimeException(print_r(sqlsrv_errors(), true));
    }
    if (!is_array($row) || $row['CountValue'] !== 42
        || !($row['DayValue'] instanceof DateTime)
        || $row['DayValue']->format('Y-m-d') !== '2026-10-19'
        || $row['Missing'] !== null) {
        throw new RuntimeException('Unexpected SQLSRV values or default types.');
    }
    echo get_debug_type($row['CountValue']), ', ',
        get_debug_type($row['DayValue']), ', ', get_debug_type($row['Missing']), PHP_EOL;
} finally {
    if (is_resource($stmt)) {
        sqlsrv_free_stmt($stmt);
    }
    sqlsrv_close($conn);
}

Ожидаемые выходные данные:

int, DateTime, null

PDO_SQLSRV

Сохраните эту отдельную программу как compare-pdo.php, и запустите php compare-pdo.php. Он намеренно оставляет получение числовых значений и дат с параметрами PDO_SQLSRV по умолчанию.

<?php
$config = [];
foreach (['SQL_SERVER', 'SQL_DATABASE', 'SQL_USER', 'SQL_PASSWORD'] as $name) {
    $value = getenv($name);
    if ($value === false || $value === '') {
        throw new RuntimeException("Set $name before running this example.");
    }
    $config[$name] = $value;
}
foreach (['SQL_DATABASE', 'SQL_USER', 'SQL_PASSWORD'] as $name) {
    $config[$name] = '{' . str_replace('}', '}}', $config[$name]) . '}';
}
$server = $config['SQL_SERVER'];
$database = $config['SQL_DATABASE'];
$pdo = new PDO(
    "sqlsrv:Server=$server;Database=$database;Encrypt=true;"
    . "TrustServerCertificate=false;LoginTimeout=30",
    $config['SQL_USER'],
    $config['SQL_PASSWORD'],
    [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8,
    ]
);
$stmt = null;
try {
    $stmt = $pdo->query("SELECT CAST(42 AS int) AS CountValue, "
        . "CAST('2026-10-19' AS date) AS DayValue, CAST(NULL AS int) AS Missing");
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    if ($row !== ['CountValue' => '42', 'DayValue' => '2026-10-19', 'Missing' => null]) {
        throw new RuntimeException('Unexpected PDO_SQLSRV values or default types.');
    }
    echo get_debug_type($row['CountValue']), ', ',
        get_debug_type($row['DayValue']), ', ', get_debug_type($row['Missing']), PHP_EOL;
} finally {
    $stmt = null;
    $pdo = null;
}

Ожидаемые выходные данные:

string, string, null

Обе программы явно запрашивают именованные ключи результатов. Эти PHP-массивы используют имена столбцов, такие как CountValue, вместо числовых индексов с отсчётом от нуля. SQL NULL превращается в PHP null в любом из API. Это не пустая строка и не отсутствующая строка результата.

Обе программы считывают реальное имя базы данных, имя пользователя и пароль из переменных окружения. Они экранируют эти значения один раз при обработке соединения драйвером PHP в стиле ODBC. Удвоение закрывающих скоб и заключение значения в фигурные скобки сохраняет специальные символы; это не переименовывает базу данных и не меняет сохранённый пароль. Для получения дополнительной информации см. раздел «Подключение к серверу».

Примеры останавливаются при ошибках и освобождают ресурсы в finally. SQLSRV сообщает о сбоях базы данных через false и sqlsrv_errors(); PDO_SQLSRV выбрасывает исключения при сбоях соединения и использует исключения при сбоях запросов в соответствии с установленным режимом обработки ошибок. В веб-приложении перехватывайте эти исключения в коде, который обрабатывает запрос. Записывайте диагностические данные в защищённые журналы вместо того, чтобы возвращать их браузеру.

После упражнения удалите compare-sqlsrv.php и compare-pdo.php, если они вам больше не нужны. Очистите переменные среды учетных данных из тестового процесса, когда закончите.

Выберите типы, кодирование и обработку ошибок

Определите, какие типы PHP ожидает ваше приложение, как оно обрабатывает текст и ошибки, а также когда освобождает ресурсы базы данных.

Решение SQLSRV PDO_SQLSRV Влияние на код приложения
Типы целочисленных результатов Нативные PHP-целые числа для столбцов SQL int. По умолчанию строки; запросы PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE поддерживают числовые типы PHP. Строгие сравнения и сериализированные результаты могут различаться. Не думайте, что каждый числовой тип SQL может быть представлен как целое число PHP или float.
Результаты по дате и времени DateTime объекты по умолчанию; ReturnDatesAsStrings выбирает строки. Строки по умолчанию; PDO::SQLSRV_ATTR_FETCHES_DATETIME_TYPE выбирает объекты. Нормализуйте представление перед сериализацией или передачей в код приложения.
Кодировка символов Задать CharacterSet => 'UTF-8' явно. UTF-8 по умолчанию; настройте его с PDO::SQLSRV_ATTR_ENCODING. Не передавайте параметр SQLSRV в PDO DSN.
Обработка ошибок Проверьте false и зафиксируйте полную коллекцию ошибок SQLSRV немедленно. Настройте PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION. Недостающая строка и запрос с ошибкой требуют другой обработки.
Повторное использование параметров Связывайте переменные по ссылке в sqlsrv_prepare() дескрипторах. Используйте bindParam() для обозначения переменной или bindValue() для её текущего значения. Переназначение переменной влияет на привязку по ссылке, а не на привязку предыдущего значения.
Cleanup Освободите инструкции, затем закройте ресурс соединения. Ссылки на оператор release, затем объект PDO. Запрос может поддерживать PDO-соединение активным после того, как другая ссылка установлена в null.

Если вы мигрируете существующее приложение, тестируйте эти варианты поведения на репрезентативных значениях данных перед изменением кода базы данных. Включайте текст с не-ASCII символами, SQL NULL, даты, точные десятичные значения и параметры вывода хранимых процедур. Также сравните, как ваш фреймворк настраивает атрибуты PDO. Замена имён функций сама по себе не переносит обработку ошибок, привязку ссылок или возвращаемые типы PHP.

Для процесса записи и чтения на примере с обоими API используйте руководство по программированию. Для повторного выполнения и типизированных входных данных используйте функции выполнения запросов Compare.

Знайте, что делает каждый компонент

Ваш выбор расширения меняет API PHP и его конверсии типов. Оба расширения используют ODBC для связи с сервером, шифрования соединений и аутентификации. Операционная система предоставляет проверенные сертификаты и сервисы, такие как проверка подлинности Windows или Kerberos. Целевой объект SQL управляет правами, схемой и поддерживаемыми операторами T-SQL.

Программы для сравнения используют SQL аутентификацию в SQL Server. Для База данных SQL Azure, Управляемый экземпляр SQL Azure, Azure Synapse Analytics, SQL database in Fabric или Warehouse in Fabric настраивайте конечную точку сервиса и поддерживаемую аутентификацию перед повторным использованием шаблона выборки. Оба продукта Fabric требуют аутентификации Microsoft Entra ID; Warehouse также требует отключения нескольких активных наборов результатов (MARS). Успешное сравнение типов на SQL Server не доказывает, что разная цель поддерживает все функции, указанные в этом обзоре.

Что дают оба расширения

  • Интегрированная аутентификация, SQL-аутентификация и аутентификация Microsoft Entra ID, в зависимости от поддержки целевого объекта. Управляемая идентификация не использует пароль приложения; ActiveDirectoryServicePrincipal использует идентификатор клиента и секрет клиента. Для получения дополнительной информации см. раздел «Подключение к серверу».
  • Параметризованные запросы, подготовленные выражения и направленные (входные/выходные) параметры. Для получения дополнительной информации см. разделы «Сравнение функций исполнения » и «Использование направленных параметров».
  • Транзакции, входные параметры потока для больших символьных и бинарных значений, а также параметры табличного типа.
  • Всегда зашифрованы, включая защищённые анклавы, где драйвер ODBC и целевая SQL Server поддерживают их. Для получения дополнительной информации смотрите раздел «Использование Always Encrypted с драйверами Microsoft для PHP для SQL Server».
  • Подключения к SQL Server, База данных SQL Azure, Управляемый экземпляр SQL Azure, Azure Synapse Analytics, SQL Database в Microsoft Fabric и Warehouse в Microsoft Fabric. Функции аутентификации и SQL различаются в зависимости от целевого объекта; см. соединения Azure и Fabric.