2010-08-12 9 views
7

Podczas uzyskiwania dostępu do bazy danych programu Microsoft SQL z PHP przy użyciu PDO_ODBC z następującego kodu, Mam problem kodowania. Po wyprowadzeniu tekst z DB jest zniekształcony.kodowania znaków problem z PDO_ODBC

$dsn = "odbc:DRIVER={SQL Server};SERVER=$hostname;DATABASE=$database;charset=UTF-8"; 
$pdo = new PDO($dsn,$username,$password); 
$sql = "SELECT text FROM atable"; 
$result = $PDO->query($sql); 
while($data = $result->fetchObject()){ 
    $values[] = $data->text; 
} 
dpm($values); 

garbled output http://image.bayimg.com/naomcaacd.jpg

to odbywa się z modułu Drupal. Wszystko w Drupal zostało stworzone do pracy z UTF-8. Najczystszym rozwiązaniem byłoby pobranie danych z bazy danych w UTF-8 lub konwersja UTF-8 przed wyprowadzeniem.

Próbowałem je bez powodzenia

  • $dsn = "odbc:DRIVER={SQL Server};SERVER=$hostname;DATABASE=$database;client_charset=utf-8"
  • $dsn = "odbc:DRIVER={SQL Server};SERVER=$hostname;DATABASE=$database;charset=utf-8"
  • $pdo->exec('SET NAMES utf8') po new PDO(...)
  • $pdo->exec('SET CHARACTER SET utf8'); po new PDO(...)

PS: Kod jest obecnie rozwijany w systemie Windows, ale to ma pracować także nad GNU/Linux.

Odpowiedz

5

Podczas pracy w systemie Linux i przy użyciu sterownika FreeTDS, zestaw znaków dla klienta można skonfigurować za pomocą ustawienia client charset w pliku freetds.conf. Aby pliku freetds.conf stosowane przy użyciu PDO ODBC i unixodbc, trzeba skonfigurować źródło danych ODBC przy użyciu ODBC-combined configuration. Gdy do konfigurowania źródła danych ODBC jest używane ODBC-only configuration, plik freetds.conf nie jest używany. Dzięki temu udało mi się pobrać i wstawić dane UTF-8 z/do bazy danych MS SQL Server.

Będąc Linux/Unix facet, nie byłem w stanie zrozumieć/znaleźć sposób jak skonfigurować zestaw znaków używany podczas PDO ODBC jest używany w systemie Windows. Moje niejasne zrozumienie polega na tym, że po skonfigurowaniu na poziomie systemu źródło danych ODBC można skonfigurować tak, aby używało zestawu znaków bazy danych de SQL Server lub konwertowało na zestaw znaków komputera klienckiego.

+0

Gdybym użyć konfiguracji ODBC tylko i połączyć z PHP PDO ODBC, nie mogę dostać UTF-8 danych. –

2

Podczas ustawiania kodowania znaków na UTF-8, będzie trzeba także kodować zapytania jako UTF-8 i zdekodować wyniki. Zestaw znaków informuje operatora, że ​​mówisz w UTF8 natywnie. W związku z tym należy przekonwertować kod UTF8 z powrotem do tego, co PHP rozumie (ASCII lub mbstring).

$dsn = "odbc:DRIVER={SQL Server};SERVER=$hostname;DATABASE=$database;charset=UTF-8"; 
$pdo = new PDO($dsn,$username,$password); 
$sql = utf8_encode("SELECT text FROM atable"); 
$result = $PDO->query($sql); 
while($data = $result->fetchObject()){ 
    $values[] = utf8_decode($data->text); 
    // possibly also: $values[] = utf8_decode($data[utf8_encode('text')]); 
} 
dpm($values); 
+0

Cóż, jak powiedziałem, robi się to z modułu Drupala. Drupal oczekuje, że wszystkie ciągi będą kodowane w UTF-8, a także wyprowadza swoje strony z zestawem kodowania do UTF-8. Po skonfigurowaniu źródła danych ODBC do używania UTF-8 (patrz moja odpowiedź), PDO zwraca zakodowane dane UTF-8 poprawnie wyprowadzone z funkcją dpm(). Wywołanie utf8_decode() na danych z PDO spowoduje wygenerowanie zniekształconych wyjść, ponieważ ciąg będzie wyświetlany na stronie kodowanej w UTF-8. –

+0

Dzięki, działało idealnie dla mnie.! – Dharmavir

0

Można użyć tego kodu, aby rozwiązać swój problem:

$result = odbc_exec($this->con, $sql);  
$data = fetch2Array($result); 

private function fetch2Array($result){  
    $rows = array(); 

    while($myRow = odbc_fetch_array($result)){ 
     $rows[] = $this->arrayToUTF($myRow); 
    } 
    return $rows; 
} 

private function arrayToUTF($arr){ 
    foreach ($arr as $key => $value) { 
     $arr[$key] = utf8_encode($value); 
    } 
    return $arr; 
} 
+0

Pytanie pytanie o rozwiązanie z PDO, ta odpowiedź nie korzysta z PDO. Ponadto sugerowane rozwiązanie jest zbędne w stosunku do wcześniejszej wersji Veggivore (tj. Konwertuj wartości za pomocą utf8_encode()). –

0

Można użyć tego kodu, aby rozwiązać swój problem:

Pierwszy post danych Konwersja

'$word = iconv("UTF-8","Windows-1254",$_POST['search']);' 

I Odczyt danych Konwersja

while($data = $result->fetchObject()){ 
    $values[] = iconv("Windows-1254", "UTF-8",$data->text)); 
} 

SQL String

$sql = "SELECT * FROM yourtables WHERE text LIKE '%{$word}%'"; 
or 
$sql = "SELECT * FROM yourtables"; 
Powiązane problemy