Подключение к MSSQL серверу с помощью PHP: различия между версиями

Материал из Wiki МИАЦ ВО
Перейти к навигации Перейти к поиску
 
(не показано 14 промежуточных версий этого же участника)
Строка 54: Строка 54:
     text size = 2147483647
     text size = 2147483647


[MSSQL_TEST]
[MSSQL_TDS]
   host = 172.16.130.20
   host = 172.16.130.20
   port = 1433
   port = 1433
Строка 63: Строка 63:
</pre>
</pre>
Проверка
Проверка
<pre>tsql -S MSSQL_TEST -U username -P password</pre>
<pre>tsql -S MSSQL_TDS -U username -P password</pre>
Если подключается — переходим дальше.
Если подключается — переходим дальше.


===Настройка unixODBC===
===Настройка unixODBC===
/etc/odbcinst.ini
<pre>$ odbcinst -j
unixODBC 2.3.11
DRIVERS............: /usr/etc/odbcinst.ini
SYSTEM DATA SOURCES: /usr/etc/odbc.ini
FILE DATA SOURCES..: /usr/etc/ODBCDataSources
USER DATA SOURCES..: /root/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8
</pre>
Смотрим, где лежат файлы настроек odbc.ini и odbcinst.ini и их уже редактируем
 
odbcinst.ini
<pre>
<pre>
[PostgreSQL]
Description=ODBC for PostgreSQL
Driver=/usr/lib/psqlodbcw.so
Setup=/usr/lib/libodbcpsqlS.so
Driver64=/usr/lib64/psqlodbcw.so
Setup64=/usr/lib64/libodbcpsqlS.so
FileUsage=1
[MySQL]
Description=ODBC for MySQL
Driver=/usr/lib/libmyodbc5.so
Setup=/usr/lib/libodbcmyS.so
Driver64=/usr/lib64/libmyodbc5.so
Setup64=/usr/lib64/libodbcmyS.so
FileUsage=1
[FreeTDS]
[FreeTDS]
Description=TDS driver (Sybase/MS SQL)
Description=TDS driver (Sybase/MS SQL)
Driver=libtdsodbc.so
Driver=/usr/lib64/libtdsodbc.so
Setup=libtdsS.so
Setup=/usr/lib64/libtdsS.so   # если Setup нет — просто убери эту строку
CPTimeout=
UsageCount=1
CPReuse=
 
[ODBC Driver 18 for SQL Server]
Description=Microsoft ODBC Driver 18 for SQL Server
Driver=/opt/microsoft/msodbcsql18/lib64/libmsodbcsql-18.3.so.2.1
UsageCount=1
UsageCount=1
</pre>
</pre>
/etc/odbc.ini
Редактируем секцию FreeTDS
 
odbc.ini
<pre>
<pre>
[MSSQL_TEST]
[MSSQL_TDS]
Description = My MS SQL Server via FreeTDS
Description = My MS SQL Server via FreeTDS
Driver      = FreeTDS
Driver      = FreeTDS
Servername  = MSSQL_TEST
Servername  = MSSQL_TDS
Database    = www_new
Database    = www_new
Port        = 1433
Port        = 1433
Строка 88: Строка 121:
TextSize    = 2147483647
TextSize    = 2147483647
</pre>
</pre>
Servername  берется из freetds.conf. Driver - Название секции в файле  odbcinst.ini
Проверка:
Проверка:
<pre>isql -v my_mssql username password</pre>
<pre>isql -v MSSQL_TDS username password</pre>
Должно выдать:
Должно выдать:
<pre>Connected!
<pre>Connected!
Строка 96: Строка 131:
===Подготовка===
===Подготовка===
Перезагрузи FPM
Перезагрузи FPM
<pre>sudo systemctl restart php8.2-fpm</</pre>
<pre>sudo systemctl restart php8.2-fpm</pre>
 
===Проверка PHP-подключения===
===Проверка PHP-подключения===
Создай test_mssql.php:
Создай test_mssql.php:
<pre><?php
<pre><?php
try {
try {
     $pdo = new PDO("odbc:my_mssql", "username", "password");
     $pdo = new PDO("odbc:MSSQL_TDS", "username", "password");
     $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
     $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);


Строка 116: Строка 152:
<pre>php test_mssql.php</pre>
<pre>php test_mssql.php</pre>
Если всё в порядке — увидишь список баз данных.
Если всё в порядке — увидишь список баз данных.
===Замечания и интересные моменты===
===Замечания и интересные моменты===
====текстовые поля====  
====текстовые поля====  
текстовые поля не дб nvarchar - Такие поля будут обрезаться драйвером. Нужно обязательно varchar.<br>
текстовые поля не дб nvarchar - Такие поля будут обрезаться драйвером. Нужно обязательно varchar и лучше длиной не менее 255.<br>
====Получение последней вставленной строки====
====Получение последней вставленной строки====
При работе через этот драйвер не работает- определение последней вставленной строки
При работе через этот драйвер не работает- определение последней вставленной строки
Строка 133: Строка 170:
<pre>
<pre>
$val10 = (float)str_replace(',', '.', $val10);
$val10 = (float)str_replace(',', '.', $val10);
</pre>
==ODBC Driver 18 for SQL Server на Alt Linux==
====Скачиваем RPM (например, для RHEL 9 — подходит для AltLinux x86_64):====
<pre>wget https://packages.microsoft.com/rhel/9/prod/msodbcsql18-18.4.2.1-1.x86_64.rpm</pre>
====Устанавливаем:====
<pre>sudo rpm -Uvh msodbcsql18-18.4.2.1-1.x86_64.rpm</pre>
====Расположение файла odbcinst.ini====
<pre>$ odbcinst -j
unixODBC 2.3.11
DRIVERS............: /usr/etc/odbcinst.ini
SYSTEM DATA SOURCES: /usr/etc/odbc.ini
FILE DATA SOURCES..: /usr/etc/ODBCDataSources
USER DATA SOURCES..: /root/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8</pre>
Тут смотрим, где находится файл odbcinst.ini
====Пример odbcinst.ini для MS ODBC Driver 18====
<pre>[ODBC Driver 18 for SQL Server]
Description=Microsoft ODBC Driver 18 for SQL Server
Driver=/opt/microsoft/msodbcsql18/lib64/libmsodbcsql-18.so
UsageCount=1
</pre>
✅ Важное:
* Имя секции обязательно [ODBC Driver 18 for SQL Server] — PHP расширение sqlsrv ищет именно его.
* Путь Driver= указывает на установленную библиотеку MS ODBC.
* UsageCount=1 — стандартное поле для unixODBC.
* Другие поля (Setup=…, FileUsage=…) для MS драйвера не нужны.
====Проверяем драйвер:====
<pre>odbcinst -q -d
[ODBC Driver 18 for SQL Server]
</pre>
====Проверка DSN (не обязательно для PHP PDO)====
Если нужен DSN в unixODBC, создаём /usr/etc/odbc.ini или /etc/odbc.ini:
<pre>[MSSQL_TEST]
Driver = ODBC Driver 18 for SQL Server
Server = 172.16.130.20
Database = www_new
Encrypt = yes
TrustServerCertificate = yes</pre>
Строку<br>
Driver = ODBC Driver 18 for SQL Server<br>
Менять нельзя
====Установка PHP расширений====
<pre>sudo apt-get install php8.2-sqlsrv php8.2-pdo-sqlsrv
# или для PHP 8.3
sudo apt-get install php8.3-sqlsrv php8.3-pdo-sqlsrv</pre>
====Проверяем:====
<pre>php -m | grep sqlsrv
php -m | grep pdo_sqlsrv</pre>
Должны быть оба модуля.
====Конфигурация PHP DSN====
В PHP достаточно указать DSN напрямую, '''DSN через odbc.ini необязателен''':<br>
Но можно использовать odbc.ini
<pre>[MSSQL_TEST]
Description = My MS SQL Server via MS ODBC
Driver = ODBC Driver 18 for SQL Server
Server = 172.16.130.20
Database = www_new
Encrypt = yes
TrustServerCertificate = yes</pre>
* Поле Driver указывает имя секции из odbcinst.ini, а не путь к .so.
* Можно использовать DSN через odbc: в PHP, например:
<pre>$dsn = "odbc:MSSQL_TEST";
$pdo = new PDO($dsn, $user, $pass);
</pre>
====Работа в PHP====
<pre>$host = '172.16.130.20';
$db  = 'www_new';
$user = 'your_user';
$pass = 'your_pass';
$dsn = "sqlsrv:Server=$host,1433;Database=$db;Encrypt=yes;TrustServerCertificate=yes";
try {
    $pdo = new PDO($dsn, $user, $pass, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    ]);
    echo "Connected successfully!";
} catch (PDOException $e) {
    echo "Connection failed: " . $e->getMessage();
}
</pre>
* Encrypt=yes + TrustServerCertificate=yes — для работы с TLS без проблем
* PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION — чтобы видеть ошибки
===Проверка соединения===
Через низкоуровневый тест:
<pre>/opt/microsoft/msodbcsql18/bin/sqlcmd -S 172.16.130.20 -U your_user -P 'your_pass' -d www_new
</pre>
</pre>

Текущая версия от 15:11, 21 октября 2025

И так задача - подключиться к MSSQL серверу посредством php скрипта.

Через freeTDS

1. Устанавливаем пакеты

sudo apt-get install php5-sybase php5-odbc freetds-common

2. Редактируем файл /etc/freetds/freetds.conf

# A typical Sybase server
[172.16.130.103]
	host = 172.16.130.103  (ip of the MSSQL server)
	port = 1433
	tds version = 8.0
	#client charset = WINDOWS-1251
	client charset = UTF8
	text size = 20971520

# A typical Sybase server
[172.16.130.20]
	host = 172.16.130.20  (ip of the MSSQL server)
	port = 1433
	tds version = 8.0
	#client charset = WINDOWS-1251
	client charset = UTF8
	text size = 20971520

3. А дальше, как обычно

  // подключение к СУБД и открытие базы данных
function db_connect_ms($host, $user, $passwd, $dbname)
{
     setlocale (LC_ALL, 'ru_RU.UTF-8');  
    //print "$host, $user,$passwd, $dbname";
    $link = mssql_connect($host, $user, $passwd) or die('Не могу подключиться к серверу баз данных');
    mssql_select_db($dbname) or die('Не могу открыть базу данных «'.$dbname.'»');
    return $link;
}

Вот и все.

Через ODBC драйвер

На Alt Linux доступен только этот вариант. Что бы после обновления системы, не слетел драйвер подключения к БД MSSQL

Устанавливаем пакеты

sudo apt update
sudo apt install -y php8.3 php8.3-cli php8.3-dev php8.3-odbc \
                   unixodbc unixodbc-dev freetds-bin freetds-dev \
                   build-essential

Проверка

php -m | grep odbc
odbc

Настройка FreeTDS

Открой /etc/freetds/freetds.conf:

[global]
    tds version = 7.4
    client charset = UTF-8
    text size = 2147483647

[MSSQL_TDS]
  host = 172.16.130.20
  port = 1433
  tds version = 8.0
  #client charset = WINDOWS-1251
  client charset = UTF8
  text size = 20971520

Проверка

tsql -S MSSQL_TDS -U username -P password

Если подключается — переходим дальше.

Настройка unixODBC

$ odbcinst -j
unixODBC 2.3.11
DRIVERS............: /usr/etc/odbcinst.ini
SYSTEM DATA SOURCES: /usr/etc/odbc.ini
FILE DATA SOURCES..: /usr/etc/ODBCDataSources
USER DATA SOURCES..: /root/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8

Смотрим, где лежат файлы настроек odbc.ini и odbcinst.ini и их уже редактируем

odbcinst.ini

[PostgreSQL]
Description=ODBC for PostgreSQL
Driver=/usr/lib/psqlodbcw.so
Setup=/usr/lib/libodbcpsqlS.so
Driver64=/usr/lib64/psqlodbcw.so
Setup64=/usr/lib64/libodbcpsqlS.so
FileUsage=1

[MySQL]
Description=ODBC for MySQL
Driver=/usr/lib/libmyodbc5.so
Setup=/usr/lib/libodbcmyS.so
Driver64=/usr/lib64/libmyodbc5.so
Setup64=/usr/lib64/libodbcmyS.so
FileUsage=1

[FreeTDS]
Description=TDS driver (Sybase/MS SQL)
Driver=/usr/lib64/libtdsodbc.so
Setup=/usr/lib64/libtdsS.so   # если Setup нет — просто убери эту строку
UsageCount=1

[ODBC Driver 18 for SQL Server]
Description=Microsoft ODBC Driver 18 for SQL Server
Driver=/opt/microsoft/msodbcsql18/lib64/libmsodbcsql-18.3.so.2.1
UsageCount=1

Редактируем секцию FreeTDS

odbc.ini

[MSSQL_TDS]
Description = My MS SQL Server via FreeTDS
Driver      = FreeTDS
Servername  = MSSQL_TDS
Database    = www_new
Port        = 1433
TDS_Version = 8.0
TextSize    = 2147483647

Servername берется из freetds.conf. Driver - Название секции в файле odbcinst.ini

Проверка:

isql -v MSSQL_TDS username password

Должно выдать:

Connected!
SQL>

Подготовка

Перезагрузи FPM

sudo systemctl restart php8.2-fpm

Проверка PHP-подключения

Создай test_mssql.php:

<?php
try {
    $pdo = new PDO("odbc:MSSQL_TDS", "username", "password");
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    echo "✅ Подключено!\n";
    $stmt = $pdo->query("SELECT TOP 5 name FROM sys.databases");

    foreach ($stmt as $row) {
        echo $row['name'], PHP_EOL;
    }
} catch (PDOException $e) {
    echo "❌ Ошибка: " . $e->getMessage();
}

Запусти:

php test_mssql.php

Если всё в порядке — увидишь список баз данных.

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

текстовые поля

текстовые поля не дб nvarchar - Такие поля будут обрезаться драйвером. Нужно обязательно varchar и лучше длиной не менее 255.

Получение последней вставленной строки

При работе через этот драйвер не работает- определение последней вставленной строки

SELECT SCOPE_IDENTITY();

Вместо этого нужно использовать

INSERT INTO my_table (name, value)
OUTPUT INSERTED.id
VALUES ('Test', 123);

Запрос сразу вставит данные и выведет номер последней строки.

Работа с большими числами

При очень больших числах (Больше 10 знаков), драйвер из-за русской кодовой страницы выведет 3,234235346346 10х, что будет являться строкой для PHP
Код для исправления

$val10 = (float)str_replace(',', '.', $val10);

ODBC Driver 18 for SQL Server на Alt Linux

Скачиваем RPM (например, для RHEL 9 — подходит для AltLinux x86_64):

wget https://packages.microsoft.com/rhel/9/prod/msodbcsql18-18.4.2.1-1.x86_64.rpm

Устанавливаем:

sudo rpm -Uvh msodbcsql18-18.4.2.1-1.x86_64.rpm

Расположение файла odbcinst.ini

$ odbcinst -j
unixODBC 2.3.11
DRIVERS............: /usr/etc/odbcinst.ini
SYSTEM DATA SOURCES: /usr/etc/odbc.ini
FILE DATA SOURCES..: /usr/etc/ODBCDataSources
USER DATA SOURCES..: /root/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8

Тут смотрим, где находится файл odbcinst.ini

Пример odbcinst.ini для MS ODBC Driver 18

[ODBC Driver 18 for SQL Server]
Description=Microsoft ODBC Driver 18 for SQL Server
Driver=/opt/microsoft/msodbcsql18/lib64/libmsodbcsql-18.so
UsageCount=1

✅ Важное:

  • Имя секции обязательно [ODBC Driver 18 for SQL Server] — PHP расширение sqlsrv ищет именно его.
  • Путь Driver= указывает на установленную библиотеку MS ODBC.
  • UsageCount=1 — стандартное поле для unixODBC.
  • Другие поля (Setup=…, FileUsage=…) для MS драйвера не нужны.

Проверяем драйвер:

odbcinst -q -d
[ODBC Driver 18 for SQL Server]

Проверка DSN (не обязательно для PHP PDO)

Если нужен DSN в unixODBC, создаём /usr/etc/odbc.ini или /etc/odbc.ini:

[MSSQL_TEST]
Driver = ODBC Driver 18 for SQL Server
Server = 172.16.130.20
Database = www_new
Encrypt = yes
TrustServerCertificate = yes

Строку
Driver = ODBC Driver 18 for SQL Server
Менять нельзя

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

sudo apt-get install php8.2-sqlsrv php8.2-pdo-sqlsrv
# или для PHP 8.3
sudo apt-get install php8.3-sqlsrv php8.3-pdo-sqlsrv

Проверяем:

php -m | grep sqlsrv
php -m | grep pdo_sqlsrv

Должны быть оба модуля.

Конфигурация PHP DSN

В PHP достаточно указать DSN напрямую, DSN через odbc.ini необязателен:
Но можно использовать odbc.ini

[MSSQL_TEST]
Description = My MS SQL Server via MS ODBC
Driver = ODBC Driver 18 for SQL Server
Server = 172.16.130.20
Database = www_new
Encrypt = yes
TrustServerCertificate = yes
  • Поле Driver указывает имя секции из odbcinst.ini, а не путь к .so.
  • Можно использовать DSN через odbc: в PHP, например:
$dsn = "odbc:MSSQL_TEST";
$pdo = new PDO($dsn, $user, $pass);

Работа в PHP

$host = '172.16.130.20';
$db   = 'www_new';
$user = 'your_user';
$pass = 'your_pass';

$dsn = "sqlsrv:Server=$host,1433;Database=$db;Encrypt=yes;TrustServerCertificate=yes";

try {
    $pdo = new PDO($dsn, $user, $pass, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    ]);
    echo "Connected successfully!";
} catch (PDOException $e) {
    echo "Connection failed: " . $e->getMessage();
}
  • Encrypt=yes + TrustServerCertificate=yes — для работы с TLS без проблем
  • PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION — чтобы видеть ошибки

Проверка соединения

Через низкоуровневый тест:

/opt/microsoft/msodbcsql18/bin/sqlcmd -S 172.16.130.20 -U your_user -P 'your_pass' -d www_new