2010-08-12 26 views
7

Al acceder a una base de datos Microsoft SQL desde PHP utilizando PDO_ODBC con el siguiente código, tengo un problema de codificación. Cuando se supera, el texto del DB está distorsionado.Problema de codificación de caracteres 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

Esto se hace a partir de un módulo de Drupal. Todo en Drupal está hecho para funcionar con UTF-8. La solución más limpia sería poder recuperar los datos de la base de datos en UTF-8 o convertirlos en UTF-8 antes de la salida.

he probado todas estas sin ningún éxito

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

PS: El código es desarrollado actualmente en Windows pero tiene para trabajar en GNU/Linux también.

Respuesta

5

Cuando se ejecuta en Linux y utiliza el controlador FreeTDS, el juego de caracteres para el cliente se puede configurar con la configuración client charset en el archivo freetds.conf. Para que el archivo freetds.conf se use al utilizar PDO ODBC y unixODBC, se necesita configurar el origen de datos ODBC utilizando ODBC-combined configuration. Cuando se utiliza ODBC-only configuration para configurar el origen de datos ODBC, no se utiliza el archivo freetds.conf. Con esto pude recuperar e insertar datos UTF-8 desde/hacia la base de datos de MS SQL Server.

Al ser un tipo Linux/Unix, no pude entender/encontrar la manera de configurar el juego de caracteres utilizado cuando se usa PDO ODBC en Windows. Mi vago entendimiento es que cuando se configura en el nivel del sistema, se puede configurar un origen de datos ODBC para usar el conjunto de caracteres de la base de datos de SQL Server o convertir al juego de caracteres de la computadora del cliente.

+0

Si uso la configuración de ODBC de sólo y conectarse con PHP PDO ODBC, no puedo obtener los datos UTF-8. –

2

Al configurar la codificación de caracteres para UTF-8, también deberá codificar sus consultas como UTF-8 y decodificar los resultados. El juego de caracteres le dice al conductor que hablas UTF8 de forma nativa. Como tal, necesita convertir el UTF8 a lo que PHP entiende (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

Bueno, como dije, esto se hace desde un módulo de Drupal. Drupal espera que todas las cadenas tengan codificación UTF-8, también genera sus páginas con su codificación establecida en UTF-8. Una vez que el origen de datos ODBC está configurado para usar UTF-8 (ver mi respuesta), PDO devuelve datos codificados UTF-8 emitidos correctamente con la función dpm(). Llamar a utf8_decode() sobre los datos de PDO producirá salidas ilegibles ya que la cadena se mostrará en una página codificada en UTF-8. –

+0

¡Gracias, funcionó perfectamente para mí! – Dharmavir

0

Puede utilizar este código para arreglar el 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 solicitud de pregunta para una solución con PDO, esta respuesta no utiliza PDO. Además, la solución sugerida es redundante con la versión de Veggivore hace unos años (es decir, convertir los valores con utf8_encode()). –

0

Puede utilizar este código para arreglar el problema: Convertir

Primera Post Data

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

Y convertir Leer datos

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

cadena SQL

$sql = "SELECT * FROM yourtables WHERE text LIKE '%{$word}%'"; 
or 
$sql = "SELECT * FROM yourtables"; 
Cuestiones relacionadas