2010-08-12 22 views
7

Quando si accede a un database Microsoft SQL da PHP utilizzando PDO_ODBC con il codice seguente, si verifica un problema di codifica. Quando viene emesso il testo dal DB è confuso.Problema di codifica dei caratteri con 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

Questo viene fatto da un modulo Drupal. Tutto in Drupal è fatto per funzionare con UTF-8. La soluzione più pulita sarebbe quella di poter recuperare i dati dal database in UTF-8 o convertirli in UTF-8 prima dell'output.

ho provato questi, senza alcun successo

  • $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') dopo new PDO(...)
  • $pdo->exec('SET CHARACTER SET utf8'); dopo new PDO(...)

PS: Il codice è attualmente sviluppata su Windows, ma ha lavorare anche su GNU/Linux.

risposta

5

Quando si esegue Linux e si utilizza il driver FreeTDS, il set di caratteri per il client può essere configurato con l'impostazione client charset nel file freetds.conf. Per utilizzare il file freetds.conf quando si utilizza ODBC PDO e unixODBC, è necessario configurare l'origine dati ODBC utilizzando ODBC-combined configuration. Quando ODBC-only configuration viene utilizzato per configurare l'origine dati ODBC, il file freetds.conf non viene utilizzato. Con questo sono stato in grado di recuperare e inserire dati UTF-8 da/nel database MS SQL Server.

Essendo un tipo Linux/Unix, non ero in grado di capire/trovare un modo come configurare il set di caratteri utilizzato quando ODO PDO viene utilizzato su Windows. La mia vaga comprensione è che, quando configurata a livello di sistema, un'origine dati ODBC può essere configurata per utilizzare il set di caratteri del database di de SQL Server o convertire il charset del computer client.

+0

Se uso la configurazione ODBC-only e connettersi con PHP DOP ODBC, non posso ottenere dati UTF-8. –

2

Quando si imposta la codifica dei caratteri su UTF-8, sarà necessario codificare le query come UTF-8 e decodificare i risultati. Il charset sta dicendo all'autista che parli UTF8 in modo nativo. Come tale, è necessario convertire l'UTF8 in quello che PHP comprende (ASCII o 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

Bene, come detto, questo viene fatto da un modulo Drupal. Drupal prevede che tutte le stringhe siano codificate in UTF-8, ma invia anche le pagine con la codifica impostata su UTF-8. Una volta che l'origine dati ODBC è configurata per utilizzare UTF-8 (vedere la mia risposta), PDO restituisce i dati codificati UTF-8 correttamente emessi con la funzione dpm(). Chiamando utf8_decode() sui dati da PDO si genereranno output confusi poiché la stringa verrà visualizzata in una pagina codificata UTF-8. –

+0

Grazie, ha funzionato perfettamente per me.! – Dharmavir

0

È possibile utilizzare questo codice per risolvere il problema:

$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

La domanda per una soluzione con PDO, questa risposta non sta usando PDO. Inoltre, la soluzione suggerita è ridondante con quella di Veggivore anni fa (ad esempio, converti i valori con utf8_encode()). –

0

È possibile utilizzare questo codice per risolvere il problema:

Prima Messaggio dati Conversione

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

E Leggi dati Conversione

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"; 
Problemi correlati