json encode () ¿cadenas no utf-8?
Así que tengo una matriz de cadenas, y todas las cadenas están utilizando la codificación ANSI predeterminada del sistema y se extrajeron de una base de datos sql. Por lo tanto, hay 256 diferentes valores posibles de bytes de caracteres (codificación de bytes individuales). ¿Hay alguna forma de que json_encode() funcione y muestre estos caracteres en lugar de tener que usar utf8_encode () en todas mis cadenas y terminar con cosas como "\u0082"?
¿O es el estándar para json?
8 answers
¿Hay alguna forma de que json_encode() funcione y muestre estos caracteres en lugar de tener que usar utf8_encode() en todas mis cadenas y terminar con cosas como "\u0082"?
Si tiene una cadena codificada ANSI, usar utf8_encode()
es la función incorrecta para lidiar con esto. Es necesario convertir correctamente de ANSI a UTF-8 primero. Eso ciertamente reducirá el número de secuencias de escape Unicode como \u0082
de la salida json, pero técnicamente estos las secuencias son válidas para json, no debes temerlas.
Convirtiendo ANSI a UTF-8 con PHP
json_encode
funciona solo con UTF-8
cadenas codificadas . Si necesita crear json
válido con éxito a partir de una cadena codificada ANSI
, primero debe volver a codificarla/convertirla a UTF-8
. Entonces json_encode
funcionará como está documentado.
Para convertir una codificación desde ANSI
(más correctamente asumo que tiene una cadena codificada Windows-1252
, que es popular pero erróneamente conocido como ANSI
) a UTF-8
puede hacer uso de la mb_convert_encoding()
función:
$str = mb_convert_encoding($str, "UTF-8", "Windows-1252");
Otra función en PHP que puede convertir la codificación / charset de una cadena se llama iconv
basado en libiconv . Puedes usarlo también:
$str = iconv("CP1252", "UTF-8", $str);
Nota sobre utf8_encode ()
utf8_encode()
solo funciona para Latin-1
, no para ANSI
. Así que destruirás parte de tus personajes dentro de esa cadena cuando la corras a través de ella. función.
Relacionado: ¿Qué es el formato ANSI?
Para un control más detallado de lo que devuelve json_encode()
, vea la lista de constantes predifinadas (dependiente de la versión de PHP, incl. PHP 5.4, algunas constantes permanecen indocumentadas y están disponibles en el código fuente solo hasta ahora).
Cambiar la codificación de un array/iterativamente (comentario PDO)
Como escribió en un comentario que tiene problemas para aplicar la función a una matriz, aquí es un ejemplo de código. Es siempre necesario primero cambiar la codificación antes de usar json_encode
. Eso es solo una operación de matriz estándar, para el caso más simple de pdo::fetch()
una iteración foreach
:
while($row = $q->fetch(PDO::FETCH_ASSOC))
{
foreach($row as &$value)
{
$value = mb_convert_encoding($value, "UTF-8", "Windows-1252");
}
unset($value); # safety: remove reference
$items[] = array_map('utf8_encode', $row );
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:16:58
El estándar JSON IMPONE la codificación Unicode. De RFC4627 :
3. Encoding
JSON text SHALL be encoded in Unicode. The default encoding is
UTF-8.
Since the first two characters of a JSON text will always be ASCII
characters [RFC0020], it is possible to determine whether an octet
stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking
at the pattern of nulls in the first four octets.
00 00 00 xx UTF-32BE
00 xx 00 xx UTF-16BE
xx 00 00 00 UTF-32LE
xx 00 xx 00 UTF-16LE
xx xx xx xx UTF-8
Por lo tanto, en el sentido más estricto, JSON codificado ANSI no sería JSON válido; esta es la razón por la que PHP impone la codificación unicode cuando usa json_encode()
.
En cuanto a "default ANSI", estoy bastante seguro de que sus cadenas están codificadas en Windows-1252. Se refiere incorrectamente como ANSI.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-07 07:26:01
<?php
$array = array('first word' => array('Слово','Кириллица'),'second word' => 'Кириллица','last word' => 'Кириллица');
echo json_encode($array);
/*
return {"first word":["\u0421\u043b\u043e\u0432\u043e","\u041a\u0438\u0440\u0438\u043b\u043b\u0438\u0446\u0430"],"second word":"\u041a\u0438\u0440\u0438\u043b\u043b\u0438\u0446\u0430","last word":"\u041a\u0438\u0440\u0438\u043b\u043b\u0438\u0446\u0430"}
*/
echo json_encode($array,256);
/*
return {"first word":["Слово","Кириллица"],"second word":"Кириллица","last word":"Кириллица"}
*/
?>
JSON_UNESCAPED_UNICODE (integer) Codifique caracteres Unicode multibyte literalmente (el valor predeterminado es escapar como \uXXXX). Disponible desde PHP 5.4.0.
Http://php.net/manual/en/json.constants.php#constant.json-unescaped-unicode
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-11 10:44:55
Sí, este es el comportamiento estándar para json dentro de PHP
Si lee la documentación: http://php.net/manual/en/function.json-encode.php
Verá que solo puede funcionar con datos codificados en utf-8,
Por otro lado puedes usar el primer comentario en: http://php.net/manual/en/function.json-encode.php#104278
Y crea tu propia función de codificación/decodificación trabajando con ANSI
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-07 06:38:37
Para imprimir la palabra en español, finalmente tengo la solución como la siguiente con la aplicación de dos funciones.
$conn->set_charset("utf8");
mb_convert_encoding('THE BULLOCK ÉTAGÈRE - 3 SHELVES', "UTF-8", "Windows-1252")
Donde 'THE BULLOCK ÉTAGÃRERE - 3 SHELVES' esta cadena proviene de la base de datos, así que primero tengo object conn database object para establecer el carácter como utf8 luego he codificado la palabra en español UTF-8 a Windows-1252
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-21 10:20:59
Encontré la siguiente respuesta para un problema análogo con una matriz anidada no codificada en utf-8 que tenía que codificar en json:
$inputArray = array(
'a'=>'First item - à',
'c'=>'Third item - é'
);
$inputArray['b']= array (
'a'=>'First subitem - ù',
'b'=>'Second subitem - ì'
);
if (!function_exists('recursive_utf8')) {
function recursive_utf8 ($data) {
if (!is_array($data)) {
return utf8_encode($data);
}
$result = array();
foreach ($data as $index=>$item) {
if (is_array($item)) {
$result[$index] = array();
foreach($item as $key=>$value) {
$result[$index][$key] = recursive_utf8($value);
}
}
else if (is_object($item)) {
$result[$index] = array();
foreach(get_object_vars($item) as $key=>$value) {
$result[$index][$key] = recursive_utf8($value);
}
}
else {
$result[$index] = recursive_utf8($item);
}
}
return $result;
}
}
$outputArray = json_encode(array_map('recursive_utf8', $inputArray ));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-15 12:22:51
json_encode($str,JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS|JSON_HEX_QUOT);
Que convertirá ANSI basado en Windows a utf-8 y el error no será más.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-18 03:43:14
Usa esto en su lugar:
<?php
//$return_arr = the array of data to json encode
//$out = the output of the function
//don't forget to escape the data before use it!
$out = '["' . implode('","', $return_arr) . '"]';
?>
Copie desde los comentarios del manual php json_encode. Lee siempre los comentarios. Son útiles.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-07 06:35:47