Сравнительный обзор Microsoft SQL Driver for PHP

    Поиск по «SQL Server Driver for PHP» не дал никаких результатов, и я решил написать эту статью.

    Некоторые уже в курсе, что Microsoft выпустили свой драйвер для PHP с блекджеком использованием возможностей Native SQL Client и, даже, открыли исходный код.

    Зачем он нужен?


    Во-первых, стандартный драйвер MS SQL (php_mssql.dll), который поставляется в комплекте с PHP, обладает рядом недостатков. Главным является то, что в его основе лежит библиотека ntwdblib.dll, которая больше не поддерживается Microsoft, и, больше не входит в комплект с новыми версиями MS SQL Server. Последняя версия имеет следующие проблемы:
    • Ограничение на максимальную длину поля в resultset в 255 символов;
    • Ограничение на максимальную длину переменной при вызове хранимой процедуры в те же самые 255 символов;
    • Проблема с пустыми строками при вызове хранимой процедуры;
      Если вызывать хранимую процедуру, где параметром является пустая строка, то библиотека магическим образом превратит строку в NULL.
    • Проблема с типом varchar и nvarchar размерностью больше 255 символов;
      Все что длиннее — попросту обрезается. Обходным путем является приведение типа поля к varchar(max). В этом случае все работает правильно.
    • Также ntwdblib.dll значительно уступает в скорости получения результатов Native SQL Client.
    Все вышеперечисленные проблемы решаются использованием «SQL Server Driver for PHP». Однако мы обретаем новые проблемы:
    • Отсутствие (возможно временно) нескольких очень полезных функций-аналогов старого драйвера MSSQL;
      Например получение числа измененных строк, и, до недавнего времени не было функции получения числа строк в resultset.
    • Проблемы с получением возвращенного результата из хранимой процедуры, когда возвращается несколько resultset, даже если они пусты;
      Это, конечно, можно обойти, установив флаг NOCOUNT в ON вызовом SET NOCOUNT ON перед запросом, но это не самое красивое решение.
    • При возникновении блокировки (deadlock), у нового драйвера нет удобного механизма обхода такой ситуации;
      Обходное решение — использовать PHP функцию sleep() или usleep() и, при возникновении блокировки и через пару секунд попробовать выполнить запрос снова.
    • При получении результатов новый драйвер преобразовывает данные от типа базы данных к его аналогу в PHP, хотя это с точки зрения типизации данных правильно;
      Так, например, поле с типом datetime будет преобразовано к PHP типа DateTime, а бинарные и текстовые поля к PHP Stream, что не удобно, т.к. приходится дополнительно обрабатывать полученные результаты, чтобы получить конечный, интересующий нас результат.
    • Полное отсутствие поддержки под *nix системами
      В то время как php_mssql может быть скомпилирован с использованием FreeTDS.
    • Пожалуй, самым серьезным недостатком является не всегда стабильная работа под <irony>IIS6</irony>, под IIS7 и Apache таких проблем не было замечено.
    Несмотря на такой достаточно большой список новых проблем, к драйверу от Microsoft имеет смысл присмотреться и изучить его работу в своих проектах под Windows Server и MS SQL. Проект стабильно развивается и проблемы устраняются.

    Надеюсь, этот обзор кому-нибудь пригодится.

    Спасибо за внимание!

    Комментарии 27

      +1
      Внезапно и в тему, я лично очень рад этой новости, спасибо.
        +2
        Проблема с IIS6? Вы меня пугаете мне только сегодня пришлось проект перенести с IIS7 на IIS6. Насколько серьезные проблемы со стабильностью и есть ли может какие решения? А то это администрация города, они меня загрызут если этот драйвер будет падать. А пока стояло на 7 ни разу не наблюдал ни каких происшествий с этим драйвером.
          +1
          Да, были проблемы со стабильностью под IIS6. PHP падал несколько раз в минуту в 500 ошибку в произвольных местах, закономерность я не выявил. Тестировал на двух серверах под Windows server 2003 и IIE6.

          Решений я к сожалению не знаю. На живом сервере у нас IIS7.
            0
            Мне пока везет не падает у меня на IIS6 но как говорится еще не вечер :)
            0
            А зачем переносить проект с IIS7 на IIS6?
              +2
              Я вот тоже такой вопрос задавал :) но тестовый сервер был на 7 а боевой на 6
                0
                :) Боевой сервер. Это прекрасно!
            0
            При возникновении блокировки (deadlock), у нового драйвера нет удобного механизма обхода такой ситуации;
            Обходное решение — использовать PHP функцию sleep() или usleep() и, при возникновении блокировки и через пару секунд попробовать выполнить запрос снова.

            можно пример :)
              0
              Примерно так:
              <?php
              private function query($query) {
                ...
                ...
                $qlink = sqlsrv_query($this->connectionlink, $query);
                if (!$qlink) {
                  $errNumber = $this->getErrorCode(); // получаем номер ошибки
                  // deadlock
                  if( $errNumber == 1205
                   && ( ($this->deadlockRetryCount && $this->deadlockRetryCount >= $this->deadlockRepeatCount+1) || $this->deadlockRetryCount == -1)) {
                    $this->deadlockRepeatCount++;  // число повторений
                    if($this->deadlock_retry_timeout) sleep($this->deadlock_retry_timeout); // ждем
                    return $this->query($query); // пробуем еще
                  } else {
                    // тут вызываем обработчик ошибок
                  }
                }
                return 0;
              }

              private function getErrorCode() {
                $errNumber = 0;
                $errors = sqlsrv_errors();
                if(is_array($errors)) {
                  $lastError = end(array_keys($errors)); // берем последнюю ошибку
                  $err = (int)$errors[$lastError]['code'];
                }
                return $errNumber;
              }
              ?>
              0
              Ещё благодаря усилиями MS этот драйвер и в adodb добавили.
                –1
                Вы имеете в виду php библиотеку? мне никогда не было понятно, что может сейчас оправдать ее использование? ну кроме поддержки старых проектов?
                +1
                Мы используем в своем проекте почти уже год. Все работает стабильно, мелкие проблемы обходятся. За статью спасибо, хоть и так это знал :)
                  –3
                  Мелкософт в своем стиле…

                  Полное отсутствие поддержки под *nix системами
                    0
                    И как давно под *nix системами начали использоваться dll? Нет, я правда не в курсе.
                      –2
                      а про SO фалы что-нить слышали…
                      +3
                      Право же, такие линуксоиды меня восхищают.

                      Сначала твердим что:
                      MS — дерьмо, MS SQL — дерьмо, Linux — супер.

                      Потом хотим получить в супер Linux'e поддержку дерьма дерьмом? Вам его так сильно не хватает?
                      Сколько вам килограмм выслать? :)
                        –1
                        все очень просто: «умный» заказчик хочет чтобы БД было именно на MS SQL + БД должно быть на отдельном сервере.
                        Вопрос: зачем мне для LAMP виндовый сервер? разве нельзя выпустить so под *nix?

                        Ответ: MS «отличные ребята», поэтому максимально делают привязку к своему «хорошему» софту (когда у самих почтовый сервер на *nix, по крайней мерее год назад был так точно)
                          0
                          Либо вы хреновый специалист, либо заказчик действительно умный (без кавычек). Впрочем возможны сразу оба варианта.

                          Обычно такие требования возникают когда существует корпоративное приложение и хотят сделать ряд функций к нему через веб-интерфейс. И в этом случае это ваши личные проблемы, что вы не в состоянии реализовать его, к примеру, с использованием SharePoint или просто .NET. Именно оттуда и ростут ноги.

                          Убедить заказчика в необходимости именно LAMP вы смогли, но теперь мучаетесь и страдаете проклиная MS, хотя виноваты вы.
                            –2
                            ладно окончим холивар…
                            лично мне мнение: технологии MS — зло
                      0
                      А завернуть это также под freetds реально?

                      А то ситуация «приложение под *nix, БД — MS SQL» таки иногда встречается.
                        0
                        Я думаю для этих целей лучше использовать php_mssql, он хорошо работает по никсами с freetds.

                        А вся соль нового драйвера как раз в использовании Native SQL Client, его Microsoft пока не портировали под никсы, да и врятли когда-нибудь это сделают :)
                        0
                        К сожалению при использовании этой библиотеки сталкиваюсь с ошибкой:
                        [Microsoft][Диспетчер драйверов ODBC] Источник данных не найден и не указан драйвер, используемый по умолчанию

                        [message] => The SQL Server Driver for PHP requires the SQL Server 2008 Native Client ODBC Driver (SP1 or later) to communicate with SQL Server. That ODBC Driver is not currently installed. Accessing the following URL will download the SQL Server 2008 Native Client ODBC driver for x86: go.microsoft.com/fwlink/?LinkId=137108

                        Из-за этого пока приходится отказаться от значительного прироста скорости версии 5.3.

                        Кто-нибудь сталкивался?
                          0
                          А у Ваc Native SQL Client установлен на сервере?

                          Если да, то посмотрите включены ли необходимые протоколы в SQL Server Configuration Manager -> SQL Native Client Configuration.
                            0
                            Ммм. а разве коннект должен идти через ODBC?
                            0
                            Да, разумеется. Одно но: веб с php и mssql на разных серверах (Windows). Native SQL Client на веб-сервере установлен, все 4 протокола активны.
                            Уверен, что необходимо что-то включить, но не знаю что.
                              0
                              Попробуйте установить Microsoft SQL Server 2008 Native Client.

                              Это должно помочь.
                                0
                                Сделал первым делом, не помогло.
                                Попробую на днях поэкспериментировать с другой системой.

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

                            Самое читаемое