74

Estuve lidiando con el dilema de convertir las tildes y caracteres especiales de mi sistema.

Ocurre que ahora algunos de los datos obtenidos de la BBDD que poseen tildes salen con esto: �.

Lo extraño es que pueden haber hasta 20 datos mostrados con tildes pero solo algunos salen así SANCI�N que puede estar ocurriendo?

La unica manera es colocar esto <meta http-equiv="content-type" content="text/html; charset=UTF-8">

Pero a pesar de estar en los formularios, sigue saliendo en algunos casos el �

Los datos generados dinamicamente dan ese error

DATOS DE LA CONEXION:

config.ini

;<?php
;die(); // /* No modificar sino sabe lo que hace */
;/*
[database]
driver="mysql"
host="localhost"
port="3306"
schema="bbdd"
username="root"
password="pass" 
encode="utf8" 
;*/

Conexion.php:

<?php

<?php
$file = 'config.ini.php';
$config = parse_ini_file($file, true);
$host = $config['database']['host'];
$user = $config['database']['username'];
$pass = $config['database']['password'];
$schema = $config['database']['schema'];
$encode = $config['database']['encode'];
class conexion extends mysqli

    {
    public

    function __construct($host, $user, $pass, $schema)
        {
        parent::__construct($host, $user, $pass, $schema);
        if (mysqli_connect_error())
            {
            die();
            }
        }
    }

$conexion = new conexion($host, $user, $pass, $schema);
mysqli_set_charset( $conexion, $encode);
?>
Jorgesys
  • 103,630
  • 13
  • 52
  • 124
Dev 200
  • 5,246
  • 5
  • 39
  • 80
  • 3
    Es un problema de encodage. ¿A qué nivel estará el problema? Puede ser: 1. la configuración del HTML, 2. del servidor (PHP u otro), 3. la forma en que te conectas a la BD, estableciendo la codificación a UTF-8 ó 4. la codificación de los datos en sí (que puede ser, a. una columna de una tabla, b. una tabla de la base de datos, c. la base de datos en general). Yo iría depurando en ese orden, del 1 al 4. – A. Cedano Mar 31 '17 at 13:22
  • Ya abri todos los documentos y los converti con el block de notas UTF-8 , la base de datos la converti toda a utf_8_spanish, trate de hacer otro html y meter meta utf-8 y ejecute un while y al mostrar todos los datos salen NORMAL, eso es lo que no entiendo, me meti en otro sistema que hay en el servidor en el que trabajo y salen muchos > signos, sera el navegador? o que puede ocurrir. – Dev 200 Mar 31 '17 at 13:31
  • que meta me recomiendas que coloque para que: valide los tildes y eñe, pues los que tengo escritos directamente en HTML puse los &acute y &tilde, pero como hago para los que ejecuta la base de datos? – Dev 200 Mar 31 '17 at 13:33
  • 1
    ¿Cómo conectas a la BD? PDO, MySQLi... Los datos te salen bien si los miras desde el programa de gestión de bd? El meta en el HTML es el que has mencionado en la pregunta: `` debe estar en el `
    ` de tu HTML
    – A. Cedano Mar 31 '17 at 13:33
  • Desde la base de datos salen bien , con todo y tildes y eñes, me conecto con MySQLi construct, yo revise los documentos con block de notas y decian que estaban guardados en ASCII los guarde en UTF-8 y ahora a pesar de que pongo ISO-8859-1 no se quitan los >, ants al poner ese meta e cambiaban y salia los tildes. Probe creando otro html con lo mismo y ejecute un while de los datos y salen PERFECTOS asi que no entiendo, seran las clases css? – Dev 200 Mar 31 '17 at 13:36
  • 1
    ¿Has visto si tu conexión a MySQLi tiene el charset seteado a utf-8? http://php.net/manual/es/mysqli.set-charset.php No entiendo por qué pones ISO-8859-1 Para que se vean los datos bien lo mejor es poner utf-8 en todo. En el HTML, en la BD (tablas, columnas) y al momento de conectar a la BD. – A. Cedano Mar 31 '17 at 13:40
  • sobre el UTF-8 me parecio innecesario cuando cree la conexion jejeje pues todo marcha bien (o eso creia) debo agregarlo?. Pues agregaba ese iso, porque tenia un archivo que mostraba datos de la BBDD y si le ponia utf-8 salia el >. AGREGARE LA CONEXION A LA PREGUNTA – Dev 200 Mar 31 '17 at 13:42
  • puse esto mysqli_set_charset( $conexion, 'utf8'); y se arreglo jajajaja CUANTO TE AMO – Dev 200 Mar 31 '17 at 13:46
  • 1
    [Continuemos el debate en el chat](http://chat.stackexchange.com/rooms/56368/discussion-between-a-cedano-and-victor-a). – A. Cedano Mar 31 '17 at 14:13
  • 2
    A mi una vez me pasó lo mismo y luego de revisar y revisar TODO lo posible, me di cuenta que el problema estaba en la codificación del notepad++.... También suele pasar – Adriana Hernández Jul 12 '17 at 14:20
  • @AdrianaHernández yo casi me suicido jajaja literal, no recuerdo si es en esta pregunta u otra parecida, donde revise hasta el sublime text, para ver su configuracion, ese dia que revise el sistema tuve que crear de cero todos los archivos y guardadlos con el wordpad creo en UTF-8 – Dev 200 Jul 12 '17 at 14:23
  • 1
    Creeme que te entiendo perfectamente lo que te sucedió porque yo también casi me suicido en defensa propia cuando me pasó a mi jajaja... Pero quisiera saber al final como lo resolvistes tu, o sea cual de los niveles que se plantean en la respuesta aceptada era tu caso? el 3 el de la configuración de la conexión? – Adriana Hernández Jul 12 '17 at 14:32
  • @AdrianaHernández en este caso sirvio mas usar el CHARSET que los otros procedimientos que están en la respuesta, es decir la respuesta 2. Pero ocurre que a pesar de eso se presentaron otros problemas: https://es.stackoverflow.com/questions/58626/por-que-si-poseo-un-formato-de-codificaci%C3%B3n-determinado-aparecen-caracteres-esp – Dev 200 Jul 13 '17 at 02:06
  • @AdrianaHernández algunos archivos seguian rebeldes, asi que tuve que agregar etiquetas meta con utf-8, guardar los archivos con formato utf-8, cambiar el cotejamiento de la BD a utf-8 y agregar unicode. Es decir, revise con la respuesta de cedano y se habia calmado la cosa, luego tuve que hacer otra pregunta por que otros archivos estaban mal editados por asi decirlo, y surgio la respuesta de Stefan Nolde que esta en la pregunta de arriba, tuve que guardar con bloc de notas, luego de eso comento la respuesta de cedano donde resalto: mysqli_set_charset y guardar en UTF-8 con bloc de notas – Dev 200 Jul 13 '17 at 02:07
  • @AdrianaHernández en los comentarios de esa pregunta voy poco a poco resolviendo el dilema, a pesar de agregar una respuesta propia con una solucion que consegui, la forma fue incorrecta, al final cambie todo a utf-8 y se acomodo. conclusion luego de una tesis, primero respuesta 2, luego verificar si estan guardados en UTF-8 listo :), – Dev 200 Jul 13 '17 at 02:09
  • 1
    ¿No sería mas facil que provaras de cargar-le el encabezado HTML con la etiqueta UTF-8 al archivo php?, Pruebalo antes de intentar buscar un error de configuración inexistente... – Pol Flórez Viciana May 27 '18 at 00:59
  • @PolFlórezViciana no recuerdo en que parte esta anotado porque hay muchos comentarios, pero si mal no recuerdo, incluso los archivos PHP tenian la etiqueta meta y sin embargo no funcionaban, incluso en otros modulos del sistema (que realizaron otras personas) tenian tambien el mismo error a pesar de estar presentes las etiquetas. – Dev 200 May 28 '18 at 14:07
  • 1
    Es importante que verificar todo el recorrido de los datos con el mismo charset y todo el recorrido significa - HTML Presentación - PHP (o el que uses) Lenguaje Intermedio - MySQL Base de datos – PaulRM May 16 '19 at 21:33

5 Answers5

86

Cuando la codificación falla al presentar nuestra información es necesario emprender un camino de retorno hacia los datos para determinar dónde está el problema.

Cuando digo camino de retorno quiero decir que debemos empezar a revisar en la superficie e ir profundizando, para depurar el problema. Un ejemplo de camino de retorno sería :

Documento                          (HTML-Javascript-CSS, etc)   > Nivel 1
   Servidor                        (PHP u otro lenguaje)        > Nivel 2
      Conexión a la Base de Datos  (PDO, MySQLi u otros)        > Nivel 3 
          Configuración de la BD   (MySQL u otros)              > Nivel 4

Considero que es un método inteligente de depuración, pues en este caso los datos que se presentan en nuestra pantalla son sacados de una base de datos a través de un lenguaje de servidor y presentados en pantalla. Si revisamos en este orden siempre llegaremos al fondo del problema, pero por niveles. Es algo lógico : no se puede llegar al fondo sin pasar por la superficie :)

Además, aquí lo más precioso son los datos, así que, cuanto menos los toquemos o alteremos, mejor. Eso implica también que es muy importante al crear la base de datos configurar adecuadamente la BD misma, así como cada tabla y cada columna... así no tendremos que estar manipulando su estructura, lo cual podría ser un riesgo sobre todo si la BD ya tiene información , pues como es sabido podríamos perderla o provocar errores en los datos... pero ese es ya otro asunto.

Entonces empezamos a revisar desde la superficie hacia el fondo para ver dónde está el problema.

Nota: Antes de emprender este camino de retorno, consideremos un posible Nivel 0 de revisión. Es posible que si hemos trabajado nuestro contenido en cualquier editor de texto como Notepad u otros, la codificación del documento no sea la adecuada. Así que, según el editor, sería conveniente verificar la codificación que ha sido establecida en nuestro archivo. Esto sólo en el caso de que hayamos tomado el texto de algún editor.

Este Nivel 0 es importante, sobre todo si tenemos mal configurada la codificación en el editor y pensemos seguir introduciendo datos en la base de datos con una codificación que no es la que necesitamos.

  1. La configuración del HTML

    • Colocar lo siguiente en el <head>:

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">


  1. La configuración del servidor (PHP u otro)

    mb_internal_encoding("UTF-8");

    O bien: default_charset (Desde PHP 5.6+ viene establecido a UTF-8 por defecto).

    ini_set("default_charset", "UTF-8");

NOTA MUY IMPORTANTE: Aquí me refiero a una configuración global de PHP, no a aplicar funciones de codificación/decodificación sobre los datos constantemente, lo cual sería un error (el cual muchos recomiendan, por desconocimiento, en respuestas a casos parecidos a este). Cuando tengamos problemas con la codificación a nivel de PHP resolvámoslo de raíz, en la configuración, no aplicando soluciones a medio camino que nos mantendrán esclavizados aplicando constantemente funciones como utf8_encode a los datos.


  1. La forma en que te conectas a la BD, estableciendo la codificación a UTF-8
    • En el caso de MySQLi

        /* cambiar el conjunto de caracteres a utf8 */
      
        if (!$mysqli->set_charset("utf8")) {
            printf("Error cargando el conjunto de caracteres utf8: %s\n", $mysqli->error);
            exit();
      
        } else {
            printf("Conjunto de caracteres actual: %s\n", $mysqli->character_set_name());
        }
      

      Ver: mysqli::set_charset

    • En el caso de PDO

      Se puede hacer enviando el siguiente atributo a los parámetros de conexión:

PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'". Ejemplo:

           $options = array(
                  PDO::ATTR_EMULATE_PREPARES => false, 
                  PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, 
                  PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"
               );
           try {
                 # Intentar la conexión 
                 $pdo = new PDO($dsn, $usr, $pwd, $options);
           }
           catch (PDOException $e) {
                 # Escribir posibles excepciones en el error_log
                 error_log($e->getMessage(),0);
           }
           ...

Se puede hacer también poniendo el charset en la cadena del DSN, como se explica en esta Nota del Manual de PHP. Por ejemplo:

        $pdo = new PDO("mysql:host=localhost;dbname=DB;charset=UTF8");

  1. La codificación de los datos en sí (que puede ser: a. una columna de una tabla, b. una tabla de la base de datos, c. la base de datos en general).

Yo iría depurando en ese orden, del 1 al 4.

Como dices que en algún escenario se ve correctamente, parece que el problema está en el nivel 3.

Verifica que cuando te conectas a la Base de Datos estás estableciendo la codificación a UTF-8.

A. Cedano
  • 86,578
  • 19
  • 122
  • 221
  • 4
    **NOTA ADICIONAL:** Tambien ayuda usar **mysqli_set_charset( $conexion, "utf8");** Directamente en el documento que no funciona Y Por otro lado: **abrir en bloc de notas y guardar el archivo con codificacion UTF-8** – Dev 200 May 11 '17 at 12:32
  • 2
    te falta tambien despues de Configuración de la BD [Configuracion de la tabla](https://dev.mysql.com/doc/refman/5.7/en/charset-table.html) – JackNavaRow Dec 19 '17 at 18:20
  • No para todo el mundo @FranciscoNúñez, hay quienes siguen aconsejando *soluciones a medio camino*, [mira aquí un ejemplo muy reciente](https://es.stackoverflow.com/a/133602/29967). – A. Cedano Jan 25 '18 at 04:18
  • falto la configuracion global de mysql – JackNavaRow Feb 13 '18 at 15:50
  • @A.Cedano Amigo por más que intento todo lo que comentaste nada me funciona. en phpmyadmin los valores de las columnas tienen sus acentos, pero cuándo los muestra en la vista salen con los caracteres extraños, por ejemplo: Bogotá sale así: Bogotá . que mas podría ser? tengo 2 días en esto y nada que hallo la solución. – JulianProg Jan 14 '20 at 16:35
  • @JulianProg hola, una pregunta, me podrias decir como solucionaste tu problema? Por favor – Mayra Ximena Vargas Aug 29 '20 at 05:17
  • @MayraXimenaVargas Hola! estaba trabajando en proyecto colaborativo, algunos programadores usaban VSC y otros Sublime Text, cada vez que alguien editaba desde VSC la codificación del archivo se modificaba, ese era el problema en este caso. – JulianProg Aug 30 '20 at 15:20
  • Sólo reiterar del 1er comentario, que aún falta mencionar la codificación del archivo en si desde el editor de archivos (html, php, css, etc.), que seguramente fue la causa real del problema, ya que no es extraño que en forma predeterminada se use Windows-1252 en Windows y Mac Roman en MacOS. – Sal Jul 29 '21 at 17:44
16

Prueba como indica @A. Cedano

También puedes forzar UTF-8 desde el .htaccess

https://www.w3.org/International/questions/qa-htaccess-charset.en

6

Saludos has probado utilizando utf8-default collation.

introducir la descripción de la imagen aquí

Hector Lara
  • 832
  • 7
  • 11
4

Si no quieres cambiar la codificacion de tu pagina web puedes escrbir lo siguiente:

á -> &aacute;                                  
é -> &eacute;                
í -> &iacute;                 
ó -> &oacute;           
ú -> &uacute;           
ñ -> &ntilde; 

https://www.gestiweb.com/?q=content/problemas-html-acentos-y-eñes-charset-utf-8-iso-8859-1

ErnestoRM
  • 1,749
  • 1
  • 8
  • 20
  • 1
    y como colocaría eso, si la data viene de una petición a la base de datos? –  Nov 04 '18 at 00:06
  • 1
    esto solo es útil si la información que pones es estática y controlas escribir cada una de las indicaciones que das –  Nov 04 '18 at 00:07
2

Tuve ese mismo problema extrayendo el titulo de uno de mis productos de la base de datos. Resulta que el producto terminaba con a palabra Ocasión pero este me la mostraba de esta forma.

introducir la descripción de la imagen aquí

El problema se debía a que yo estaba usando una función de PHP llamada substr() y descubrí que esa función no respeta los caracteres UTF-8

Así que decidí colocar otra función de PHP que se utiliza de la misma manera que la anterior ya mencionada, esta se llama mb_substr() una vez coloque esta función en mi proyecto, deje de tener este molesto problema con los caracteres extraños.

Ejemplo:

$texto = 'Ocasión';
echo substr($texto, 0, 3); // imprime: Оcasi�n
echo mb_substr($texto, 0, 3); // imprime: Ocasión

No hay que ser un experto para darse cuenta que ambas de utilizan de la misma forma, hacen el mismo trabajo que es para acortar un texto que es muy largo, solo que una respeta los caracteres UTF-8 y la otra no lo respeta.

Espero que mi respuesta haya sido de gran ayuda, un saludo