Возникла задача получать данные из SQL Server в PHP.
Все бы ничего, но кодировка у MSSQL стоит SQL_Latin1_General_CP850_CI_AS.
Нужно получать данные в UTF-8.
Предполагаю два пути:
— Существование таблетки вида SET NAMES UTF-8. Существует ли нечто подобное в MSSQL?
— COLLATE каждого столбца во время запроса. COLLATE во что? Списки collation нашел, но ничего похожего на юникод не увидел.
Сейчас получаемые данные выглядят как знаки вопроса и подобрать кодировку для iconv под это дело не удается, да и не хотелось бы это делать через iconv.
p.s. SQL Server 8.0 — если не ошибаюсь, то это двухтысячный.
А каким, кстати, драйвером пользуетесь?
У меня при использовании SQL Server Driver for PHP никаких проблем с UTF-8 не возникает. Правда я пользую SQL Server 2008, но этот драйвер должен быть совместим и с 2000, емнип.
Попробуйте тот который от майкрософта (php_sqlsrv_*.dll), емнип PDO со второй версии поддерживается. По ссылке есть инсрукции по установке и ссылки на загрузку. По идее понадобится sql native client и сам драйвер под подходящую сборку php. Как в yii настроить collation на уровне соединения я не знаю, но в Zend настраивается с этим драйвером без проблем.
Поставил, не хочет он подключаться к 2000-му серверу, говорит: This extension requires either the Microsoft SQL Server 2008 Native Client (SP1 or later) or the Microsoft SQL Server 2008 R2 Native Client ODBC Driver to communicate with SQL Server.
Этот Native Client это что-то, что можно поставить поверх сервера или что?
На сайте Microsoft написано, что ставить туда, где запускается PHP. Поставил, ничего не изменилось. Его как-то надо настраивать / запускать?
Точно ставить не на сервер с SQL Server?
Нет, ничего настраивать не нужно, ставится на машину на которой крутится php. Для тестирования работоспособности связки для начала откройте документацию по этому драйверу (либа предоставляет свои функции для подключения выборки и т.д.) и проверьте на каком-нибудь простеньком скрипте типа «подкключиться; select 123; print_r(результат);». Далее в зависимости от результата проверки работоспособности драйвера в целом либо приводите драйвер в чувства, либо ищзите как его скрутить с yii.
Так я пока и сделал. Но согласитесь, это костыль :-)
А в обратную сторону у меня так не получилось. Не могу выбрать строки по where с русскими буквами.
Collation базы SQL_Latin1_General_CP850_CI_AS, iconv при конвертации в cp850 ругается на illegal characters… Во что конвертировать мое utf-8 чтобы sql server понял?
С обратной ситуацией попробовать можно так (продолжение костылей):
входящую строку конвертим iconv из utf8 в cp 1251
затем вставляем ее в запрос в котором есть преобразования типа
convert (nvarchar,table.field) collate CYRILLIC_GENERAL_CI_AS as fieldNewName
Обе ссылки уже находил. По первой нет ответа на мой вопрос. USC-2 сервер не признает как валидный collation.
По второй драйвер под *nix, а я под win, да и нет у меня проблемы с драйвером…
Вы не поверите… :-)
Весь затык оказался в том, что я ставил Native Client от 2005 сервера. Уж не знаю, куда я смотрел :-0
Поставил от 2008-го — все завелось.
С этим драйвером все работает так, как-будто и нет никаких заморочек с кодировками. Запросы с utf8 условиями, ответы тоже в utf8.
А по ссылке про Yii из-за бага/фичи Yii автор не получит некоторых специфических методов для MS SQL. Все-таки про sqlsrv Yii кое-где пока не знает, надо бы им сообщить…
Про некоторые особенности sqlsrv и к ZF коннектор не знает. Но думаю это вопрос времени, если бы дравер был под linux было бы проще, все-таки php под линуксом крутится гораздо чаще, но по моим личным наблюдениям процент людей которые используют php под iis растет, а знаит и патчи к популярным фреймворкам рано или поздно появятся.
Написал в багтрекер про вышеупомянутый баг. Fixed спустя 12 минут. o0
Про Yii я имел в виду то, что внутри инстанцировался не совсем тот класс, терялась пара методов для работы с транзакциями и кое-чего по мелочи. Для sqlsrv ничего сверх методов обычного PDO Yii не реализует. Да в общем-то ничего и не нужно, имхо.
А php у меня под апачем ;-)
Сами столбцы какого типа? в MSSQL данные хранятся в юникоде с использованием UCS2 для NCHAR, NVARCHAR, NTEXT. Попробуйте сделать CAST as NVARCHAR например, или создать таблицу с таким типом и выбрать из нее.