2010-09-12 16 views
9

Tengo un conjunto de palabras clave que se pasan a través a través de JSON de un DB (codificada UTF-8), algunos de los cuales pueden tener caracteres especiales como E, E, C, etc. Esto se usa como parte de un autocompletar. Ejemplo:Valores en UTF-8 está codificado como NULL en JSON

array('Coffee', 'Cappuccino', 'Café'); 

debo añadir que la matriz ya que proviene de la base de datos sería:

array('Coffee', 'Cappuccino', 'Café'); 

Pero JSON codifica como:

["coffee", "cappuccino", null]; 

Si imprimo éstos a través de print_r (), aparecen bien en una página web codificada en UTF-8, pero el café aparece como "café" si se usa texto/plano si quiero ver la matriz usando print_r ($ array); exit() ;.

Si codigo usando utf8_encode() antes de codificar a JSON, viene muy bien, pero lo que se imprime en la página web es "café" y no "café".

También es extraño, pero json_last_error() se ve como una función indefinida, pero json_decode() y json_encode() funcionan bien.

Cualquier ideas sobre cómo obtener datos codificados UTF-8 a partir de la base de datos a comportarse de la misma durante todo el proceso?

eidt: Aquí está la función de PHP que obtiene las palabras clave y los convierte en una sola matriz:

private function get_keywords() 
{ 
    global $db, $json; 

    $output = array(); 

    $db->query("SELECT keywords FROM listings"); 

    while ($r = $db->get_array()) 
    { 
     $split = explode(",", $r['keywords']); 

     foreach ($split as $s) 
     { 
      $s = trim($s); 
      if ($s != "" && !in_array($s, $output)) $output[] = strtolower($s); 
     } 
    } 

    $json->echo_json($output); 
} 

El método JSON :: echo_json simplemente codifica, selecciona la cabecera y las impresiones (para el uso con el prototipo)

EDIT: DB Tipo de conexión:

function connect() 
{ 

    if ($this->set['sql_connect']) 
    { 
     $this->connection = @mysql_connect($this->set['sql_host'], $this->set['sql_user'], $this->set['sql_pass']) 
       OR $this->debug("Connection Error", mysql_errno() .": ". mysql_error()); 
     $this->db = @mysql_select_db($this->set['sql_name'], $this->connection) 
       OR $this->debug("Database Error", "Cannot Select Database '". $this->set['sql_name'] ."'"); 

     $this->is_connected = TRUE; 
    } 

    return TRUE; 
} 

más actualizaciones: simple script PHP me encontré:

el envío de la matriz a través de esta función antes de hacer json_encode()
echo json_encode(array("Café")); // ["Caf\u00e9"] 
echo json_encode(array("Café")); // null 
+0

json_last_error() estuvo disponible en 5.3.0, debe ejecutar una versión anterior. Así que al menos esta extrañeza se explica ahora :) –

+0

@Anti - Gracias. Solo encontré ese error al tratar de descubrir por qué los datos codificados se codifican como NULL. – mwieczorek

+0

¿Puedes mostrar el código para 'echo_json'? –

Respuesta

1

Probar:

<?php 

function utf8json($inArray) { 

    static $depth = 0; 

    /* our return object */ 
    $newArray = array(); 

    /* safety recursion limit */ 
    $depth ++; 
    if($depth >= '30') { 
     return false; 
    } 

    /* step through inArray */ 
    foreach($inArray as $key=>$val) { 
     if(is_array($val)) { 
      /* recurse on array elements */ 
      $newArray[$key] = utf8json($inArray); 
     } else { 
      /* encode string values */ 
      $newArray[$key] = utf8_encode($val); 
     } 
    } 

    /* return utf8 encoded array */ 
    return $newArray; 
} 
?> 

Tomado de comentario en phpnet @http://php.net/manual/en/function.json-encode.php.

La función básicamente bucles aunque elementos de la matriz, tal vez usted hizo su codificación UTF-8 en la propia matriz?

+0

Esta es una función para codificar una matriz que no es UTF-8 en UTF-8. Eso está bien en sí mismo, pero probablemente no sea la solución aquí (los datos entrantes del OP * ya son * UTF-8). –

+0

¡gracias esto funciona! Hiciste mi día – nakajuice

3

json_encode parece estar disminuyendo cadenas que contienen caracteres no válidos. Es probable que sus datos UTF-8 no lleguen en la forma correcta desde su base de datos.

En cuanto a los ejemplos que das, mi suposición sería que la conexión a la base de datos no es codificación UTF-8 y sirve caracteres ISO-8859-1 en su lugar.

Se puede tratar de un SET NAMES utf8; después de inicializar la conexión?

+0

No estoy exactamente seguro de cómo hacer esto. Uso una clase mysql propia para gobernar toda la interacción SQL. ¿Es este un indicador establecido en la conexión en sí, o tiene que aplicarse a cada consulta que realizo? – mwieczorek

+0

@Mike es un marcador establecido en la conexión en sí, necesita ejecutarse solo una vez. Simplemente intente piratear la llamada en su clase de SQL por un segundo para ver si ese es el problema. –

+0

@Pekka - Ver actualizado ... es el script de conexión que ejecuto. – mwieczorek

3

Me trataron la muestra de código como este

[~]> cat utf.php 
<?php 
$arr = array('Coffee', 'Cappuccino', 'Café'); 
print json_encode($arr); 
[~]> php utf.php 
["Coffee","Cappuccino","Caf\u00e9"] 
[~]> 

Sobre la base de que yo diría que si los datos de origen es realmente UTF-8, a continuación, json_encode funciona bien. Si no es así, entonces es donde obtienes nulo. Por qué no es así, no puedo decir en base a esta información.

+0

"Café" aparece como "Caf \ u00e9" si utf8_encode() cada palabra clave tal como se agrega a array $ output (ver código). Esto funciona bien, pero cuando se agrega al DOM mediante el método de actualización de Prototype(), aparece como "Café". – mwieczorek

+0

Entonces el problema parece ser o n el lado del cliente. ¿Puedes verificar la codificación de la página (la página html, que contiene tu código Prototype) en tu navegador? –

+0

Todas las páginas HTML son UTF-8. Los valores 'nulos' que veo se muestran en Firebug: el JSON sin procesar tiene estos valores como nulos. Aquí hay una versión truncada del eco JSON: ["amok", "curry", "cerveza de barril", "cerveza ancla", "hamburguesas de media libra", nula, "comida británica", "comida inglesa", "cerveza fría" ", null," seafood "," punjabi "," halal food "," tandoori ") – mwieczorek

11

La razón podría ser la configuración actual del carácter del cliente. Una solución simple podría ser configurar al cliente con mysql_query('SET CHARACTER SET utf8') antes de ejecutar la consulta SELECT.

Update (junio de 2014)

La extensión mysql está en desuso a partir de PHP 5.5.0. Ahora se recomienda usar mysqli. Además, en lecturas posteriores, se debe evitar la forma anterior de establecer el conjunto de clientes for reasons including security.

no he probado, pero esto debería ser un sustituto ok:

$mysqli = new mysqli("localhost", "my_user", "my_password", "my_db"); 
if (!$mysqli->set_charset('utf8')) { 
    printf("Error loading character set utf8: %s\n", $mysqli->error); 
} else { 
    printf("Current character set: %s\n", $mysqli->character_set_name()); 
} 

o con el parámetro de conexión:

$conn = mysqli_connect("localhost", "my_user", "my_password", "my_db"); 
if (!mysqli_set_charset($conn, "utf8")) { 
    # TODO - Error: Unable to set the character set 
    exit; 
} 
+0

Probó esto y funciona. Gracias. –

+0

Hombre perfecto, funciona como un encanto. –

+0

te mueves por darnos la declaración mágica mysqli_set_charset ($ conn, "utf8") – sms247

0

Mi solución para codificar datos UTF8 fue:

$jsonArray = addslashes(json_encode($array, JSON_FORCE_OBJECT|JSON_UNESCAPED_UNICODE)) 
Cuestiones relacionadas