PDO dblib a parametr charset

Dzisiaj zmagałem się z kodowaniem znaków w bazach danych Microsoft SQL. Sytuacja wyglądała następująco: PHP na Linuksie, aplikacja w UTF-8, na innym serwerze kilkadziesiąt baz danych Microsoft SQL, a żeby było zabawniej bazy używały kilku kodowań znaków.

Do baz łączyłem się przez PDO ze sterownikiem dblib. Pomysł z konwertowaniem kodowania w aplikacji szybko odrzuciłem, zamiast tego zainteresowałem się parametrem charset. W dokumentacji nie jest jasno opisany, ale łatwo można się domyślić, że informuje sterownik o oczekiwanym kodowaniu.

$dbh = new \PDO('dblib:charset=UTF-8;host=10.12.34.56;dbname=nazwa_bazy', $dbUser, $dbPassword);

Niestety to nie działało. Rozwiązaniem okazała się zmiana konfiguracji FreeTDS w pliku /etc/freetds/freetds.conf.

tds version = 7.0

Ta zmiana wymusza połaczenia z użyciem wersji 7.0 protokołu. Wedle dokumentacji dopiero w tej wersji działa parametr client charset.

5 komentarzy do “PDO dblib a parametr charset”

  1. Cześć.

    Dzięki za wpis.
    Mam jednak pytanie. Czy wstawienie parametru charset=UTF-8 powoduje automatyczne konwertowanie tekstu do tego formatu? Niezależnie od tego w jakim formacie znajduje się w bazie mssql?
    U mnie to jakoś nie do końca działa… Wprawdzie strona jest rozpoznawana w przeglądarce jako UTF-8, ale to co udało mi się osiągnąć to fakt, że jedne krzaczki zamieniły się w inne. Ale nadal są to krzaczki, a nie rodzime ogonki ;)

    Na co jeszcze mógłbym zwrócić uwagę?

    Daniel.

    1. Jeśli dobrze pamiętam to tak to właśnie działało. Co bym sprawdził:
      – Czy we freetds.conf masz ustawioną wersję protokołu na 7.0?
      – Czy w bazie, z którą się łączysz dane mają odpowiednie kodowanie? Może krzaczki są już w bazie?
      – Spróbuj zapisać dane, które otrzymujesz z bazy do pliku tekstowego i otworzyć ten w plik w edytorze. Jeśli kodowanie będzie OK to pewnie ze stroną masz coś nie tak.

      Tyle mogę zasugerować na czuja.

  2. Thanks man, I was being crazy with this problem, by default my provisioner (Puppet) configures the with tds version 4.2!

  3. Michał dzięki za dobrą radę.
    Spędziłem cały wieczór czytając różne rozwiązania – niestety dopiero po kilku godzinach natrafiłem na Twój artykuł.
    W moim przypadku konfiguracja DNS bez jawnie podanej wersji nie pomagała:

    dblib:charset=UTF-8;host={$ip}:{$port};dbname={$dbname}

    ale gdy poczytałem jeszcze dokumentację, której link zamieściłeś w artykule i dodałem wersję:

    dblib:version=7.0;charset=UTF-8;host={$ip}:{$port};dbname={$dbname}

    życie stało się znów proste :)

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *