Работа с MS SQL в PHP
Работа с MS SQL в PHP: основные подходы
Основное решение: драйвер sqlsrv
Microsoft SQL Server Driver for PHP (sqlsrv)
Это официальное расширение от Microsoft, обеспечивающее наиболее производительное и функциональное взаимодействие с MS SQL Server. Оно доступно для Windows и Linux.
Как установить драйвер sqlsrv на Windows?
Скачайте соответствующий .dll файл с официального сайта и поместите в папку ext вашей PHP-инсталляции. Затем добавьте в php.ini строку extension=php_sqlsrv.dll и перезапустите веб-сервер. Версия драйвера должна соответствовать версии PHP (thread safe или нет).
Типичная ошибка:
Fatal error: Call to undefined function sqlsrv_connect()Php class sql (класс для работы с sql в php)
Расширение не загружено. Проверьте наличие файла .dll в папке ext, корректность строки в php.ini, а также используйте phpinfo() для верификации.
Как выполнить подключение к серверу?
$serverName = "localhost\SQLEXPRESS, 1433"; // экземпляр и порт
$connectionInfo = array(
"Database" => "testdb",
"UID" => "sa",
"PWD" => "password",
"CharacterSet" => "UTF-8"
);
$conn = sqlsrv_connect($serverName, $connectionInfo);
if ($conn === false) {
die(print_r(sqlsrv_errors(), true));
}
echo "Подключение успешно";Php sql insert (insert в php)
Параметр CharacterSet обязателен для корректной работы с кириллицей. Ошибки выводятся через sqlsrv_errors().
Как выполнить SELECT запрос?
$sql = "SELECT id, name FROM users WHERE active = 1";
$stmt = sqlsrv_query($conn, $sql);
if ($stmt === false) {
die(print_r(sqlsrv_errors(), true));
}
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
echo $row['id'] . ": " . $row['name'] . "\n";
}
sqlsrv_free_stmt($stmt);Php ms sql (работа с ms sql в php)
Для подготовленных запросов используйте sqlsrv_prepare и sqlsrv_execute.
Проблема: пустые строки или кракозябры при вставке кириллицы
Убедитесь, что столбец в таблице имеет тип nvarchar или nchar, и в строке подключения указан CharacterSet => "UTF-8". Для вставки используйте параметризованный запрос с префиксом N (например, N'текст') в SQL.
Альтернативные варианты
Как использовать PDO_SQLSRV?
PDO предоставляет единый интерфейс для разных баз данных. Драйвер PDO_SQLSRV устанавливается аналогично sqlsrv (файл php_pdo_sqlsrv.dll). Подключение:
$dsn = "sqlsrv:Server=localhost\SQLEXPRESS;Database=testdb";
$user = "sa";
$pass = "password";
$options = array(
PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8
);
try {
$pdo = new PDO($dsn, $user, $pass, $options);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die($e->getMessage());
}переменную sql php (использование переменных в sql-запросах php)
Пример запроса с подготавливаемым выражением:
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute([':id' => 1]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
print_r($user);Sql инъекция php (sql-инъекции в php)
Цель использования:
Абстракция от конкретной СУБД, удобство переключения между PostgreSQL, MySQL и MS SQL.
Ошибка: could not find driver
Расширение PDO_SQLSRV не загружено. Добавьте extension=php_pdo_sqlsrv.dll в php.ini.
Как подключиться через ODBC?
Используется, когда официальный драйвер не установлен, но есть ODBC-драйвер. Пример работы с функциями odbc_*:
$dsn = "Driver={ODBC Driver 17 for SQL Server};Server=localhost\SQLEXPRESS;Database=testdb;Uid=sa;Pwd=password;charset=utf8";
$conn = odbc_connect($dsn, '', '', SQL_CUR_USE_ODBC);
if (!$conn) {
die(odbc_errormsg());
}
$result = odbc_exec($conn, "SELECT * FROM users");
while ($row = odbc_fetch_array($result)) {
echo $row['name'] . "\n";
}
odbc_close($conn);Случаи использования:
Когда требуется совместимость со старыми системами или отсутствует возможность установки sqlsrv.
Проблема: кодировка
Укажите charset=utf8 в строке DSN. Иначе кириллица будет отображаться как знаки вопроса.
Расширенные примеры работы с MS SQL
1. Подготовленные запросы с выходными параметрами (sqlsrv)
$conn = sqlsrv_connect($serverName, $connectionInfo);
$sql = "{CALL sp_add_user (?, ?, ?)}";
$params = array(
array("Иван", SQLSRV_PARAM_IN),
array("ivan@mail.ru", SQLSRV_PARAM_IN),
array(&$newId, SQLSRV_PARAM_OUT, SQLSRV_PHPTYPE_INT)
);
$stmt = sqlsrv_query($conn, $sql, $params);
if ($stmt === false) die(print_r(sqlsrv_errors(), true));
echo "Новый ID: $newId";
sqlsrv_free_stmt($stmt);Новый ID: 42
В данном примере хранимая процедура sp_add_user принимает имя и email, а возвращает сгенерированный идентификатор.
2. Транзакции с откатом при ошибке
sqlsrv_begin_transaction($conn);
$sql1 = "UPDATE accounts SET balance = balance - 100 WHERE id = 1";
$sql2 = "UPDATE accounts SET balance = balance + 100 WHERE id = 2";
$stmt1 = sqlsrv_query($conn, $sql1);
$stmt2 = sqlsrv_query($conn, $sql2);
if ($stmt1 === false || $stmt2 === false) {
sqlsrv_rollback($conn);
die("Транзакция отменена");
} else {
sqlsrv_commit($conn);
echo "Перевод выполнен успешно";
}
sqlsrv_free_stmt($stmt1);
sqlsrv_free_stmt($stmt2);Перевод выполнен успешно
Транзакции гарантируют атомарность операций. При ошибке все изменения откатываются.
3. Обработка нескольких результирующих наборов
$sql = "SELECT 1 AS val; SELECT 2 AS val";
$stmt = sqlsrv_query($conn, $sql);
do {
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
echo $row['val'] . " ";
}
} while (sqlsrv_next_result($stmt));
// Результат: 1 21 2
Функция sqlsrv_next_result() переключается на следующий набор данных.
4. Получение метаданных полей
$stmt = sqlsrv_query($conn, "SELECT * FROM users");
$metadata = sqlsrv_field_metadata($stmt);
foreach ($metadata as $field) {
echo $field['Name'] . ' (' . $field['Type'] . ')' . "\n";
}id (int) name (nvarchar) email (nvarchar) created_at (datetime)
Полезно для динамического построения форм или отладки.
5. Пример с PDO_SQLSRV и транзакцией
try {
$pdo->beginTransaction();
$stmt = $pdo->prepare("INSERT INTO logs (event) VALUES (:event)");
$stmt->execute([':event' => 'Действие выполнено']);
$pdo->commit();
} catch (PDOException $e) {
$pdo->rollBack();
echo "Ошибка: " . $e->getMessage();
}(без вывода, если успешно)
PDO упрощает переключение на другую СУБД, сохраняя синтаксис запросов.