Ver Mensaje Individual
  #1 (permalink)  
Antiguo 09/09/2016, 17:02
abrahamhs
 
Fecha de Ingreso: enero-2009
Ubicación: Kandor
Mensajes: 209
Antigüedad: 15 años, 10 meses
Puntos: 11
APORTE: ¿Tienes problemas con acentos, eñes, caracteres raros en tu página?Lee esto

Si tienes problemas en tu página web, en la base de datos o al escribir archivos en disco porque te aparecen caracteres extraños al escribir acentos o eñes, el problema que tienes es de codificación de caracteres o lo que se conoce como colación.

Primero que nada decirte que eso es un gran problema y hacerlo correctamente casi nunca funciona de forma que sea multiplataforma. Esto es porque las 3 grandes sistemas operativos (Mac OS X, Linux, Windows) manejan de diferente forma sus implementaciones de caracteres como explica este link http://evertpot.com/filesystem-encoding-and-php/

Como este foro es en español se explicara como hacerlo correctamente para español.

Para que funcione correctamente la codificación para español en linux. Primero tienes que instalarle la codificación correcta en español de tu país al Sistema Operativo. Por ejemplo yo que estoy en México sería utf8_spanish_ci. Muchas distros linux hacen esto en la instalación preguntandote donde vives.

Despues, si estas usando xampp debes configurar apache y php para que usen utf8:

En apache:
[httpd.conf]
Código ini:
Ver original
  1. AddDefaultCharset utf-8

en algunas versiones de apache no se encuentra AddDefaultCharset en el lugar habitual y tienes que buscar $cfg['DefaultCharset'] = '';
en toda la instalacion o variables similares y cambiarla por $cfg['DefaultCharset'] = 'utf-8';

En php:
[php.ini]
Código ini:
Ver original
  1. default_charset = "utf-8"
  2. mbstring.internal_encoding=utf-8
  3. mbstring.http_output=UTF-8
  4. mbstring.encoding_translation=On
  5. mbstring.func_overload=0

Si estas usando una versión superior o igual a php 5.6 estos parametros estan obsoletos:
mbstring.internal_encoding
mbstring.http_input
mbstring.http_output
y basta con poner default_charset = "utf-8"

Si usas mysql toda la collation de Base de datos y tablas debe ser utf8 - utf8_spanish_ci y en la conexión:
Código PHP:
Ver original
  1. $Conex=new mysqli(.....);
  2. $Conex->set_charset("utf8");

Mucha gente resuelve sus problemas de caracteres en base de datos escapando los campos donde tienen problemas y hacen funciones para ello. Esto es parcialmente correcto. Se deben escapar los campos para evitar inyecciones sql, pero si configuraste correctamente tu apache, php y base de datos, con eso es suficiente para poder usar eñes y acentos sin problemas. Pero aún así debes evitar inyecciones sql y se hace escapando cada campo en tu insert con la siguiente función:

Código PHP:
Ver original
  1. $conexion->real_escape_string($valor);

Con estas tres configuraciones (apache, php y BD) tienes practicamente tu sitio correctamente configurado para usar los caracteres especiales que te causan problemas.

Por otro lado hay personas que usan servicios de hosting y no tienen acceso a los archivos de configuración de Apache, php. En ese caso deben solicitar un archivo .htaccess para su aplicación donde se configure utf8 correctamente y hay varias formas:

1.-
Código htaccess:
Ver original
  1. AddDefaultCharset UTF-8

2.-
Código htaccess:
Ver original
  1. <FilesMatch "\.(htm|html|css|js)$">
  2.          ForceType 'text/html; charset=UTF-8'
  3.     </FilesMatch>
3.-
Código htaccess:
Ver original
  1. <FilesMatch "\.(htm|html|css|js)$">
  2.          AddDefaultCharset UTF-8
  3.     </FilesMatch>
4.-
Código htaccess:
Ver original
  1. AddCharset UTF-8 .html
5.-
Código AddCharset UTF-8 .html:
Ver original
  1. AddType 'text/html; charset=UTF-8' html

Siendo la opción 1 la mas utilizada.
Por ultimo tus html debe tambien configurar el utf8 con la siguiente linea:

Código HTML:
Ver original
  1. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />


Ahora que tu sitio esta bien configurado, la mayoria de la APIs, bibliotecas y frameworks que uses tambien deben configurarse a utf8. Aqui pongo algunas:

Si estas usando XML-RPC:
[xmlrpc.inc]
cambia $GLOBALS['xmlrpc_internalencoding']='ISO-8859-1';
por $GLOBALS['xmlrpc_internalencoding']='UTF-8';


Si usas correo como por ejemplo PHPMailer:
Código PHP:
Ver original
  1. $mail= new PHPMailer();
  2. $mail->CharSet = 'UTF-8';

Tambien ocurre muchas veces que tienes que leer archivos que sube el usuario, como ejemplo XML y estos a pesar de estar codificados en utf8 tiran tu programa. La razón sigue siendo codificación. Existen dos codificaciones utf8 una es con BOM y otra sin BOM. ¿Que es el BOM? Es una serie de caracteres que se coloca al comienzo de los archivos unicode y que se usa como marca para indicar que el texto está codificado en UTF-8 "". Estos caracteres suelen tirar tus conexiones XML-RPC o SOAP cuando tratas de enviar archivos XML. La solución es utilizar esta función inmediatamente de la lectura de tu archivo para remover el BOM:

Código PHP:
Ver original
  1. function remove_utf8_bom($text){
  2.         $bom = pack('H*','EFBBBF');
  3.         $text = preg_replace("/^$bom/", '', $text);
  4.         return $text;
  5. }

En ocasiones, la codificación equivocada es el archivo donde esta tu código y es ese archivo el que hay que modificar. Por ejemplo en Notepad++ esta en el menú Codificación->Codificar en utf8 sin BOM. Otro ejemplo, es eclipse donde tienes que dar click en Window->Preferences y en la ventana que sale seleccionar General->Workspace y del lado derecho en Text File encoding seleccionar utf-8, lo que codificará todo tu workspace a utf-8, ya que eclipse por defecto trae cp1252.

Esto funcionara perfectamente en linux pero si usas windows y tratas de escribir archivos a disco veras que no funciona (lo explica la url que puse hasta arriba). Es entonces cuando hay que recurrir al gran repertorio de funciones que tiene PHP para codificación de caracteres, en este caso iconv. Ejemplo:

Código PHP:
Ver original
  1. $nombre="ññ.txt"
  2. $f2=fopen(iconv("UTF-8", "ISO-8859-1",$nombre),"w");
  3. fwrite($f2,$texto);
  4. fclose($f2);

ó

Código PHP:
Ver original
  1. $tam=filesize(iconv("UTF-8", "ISO-8859-1",$nombre));

Creo que así casí no debería haber problemas. Y ojo no estoy diciendo que funciones como utf8_decode y utf8_encode, html_entities, o los códigos especiales de html no deban usarse. Pero en ocasiones debes conectarte con webservices de otros paises que tienen otra codificación o leer archivos que no hiciste tu y que tienen otra codificacón, o que por una u otra razón tengas problemas con el .htaccess que solicitaste y en lo que se resuelve tengas que recurrir a estas funciones. No estas excento de algún día usar estas funciones, pero con una buena configuración básica de utf8, su uso sera minimo.

No pretendo arreglarle la vida a todo el mundo en este post, ya que no soy administrador de sistemas y por lo tanto no conozco el repertorio de configuraciones posibles que hay, pero sí les dejé algunos tips para asegurarse de que todo funciona como debería.

En resumen se tiene que configurar todo en utf-8 (Sistema operativo, Base de datos, Lenguaje de programación de servidor[PHP en este casó], conexiones a base de datos, html, frameworks y bibliotecas que uses, conexiones de Web services ) y si se te presenta algún carácter de estos es porque algo se te pasó. Con estas configuraciones solo se debe presentar el problema al escribir archivos a disco en windows y arriba he colocado como solucionarlo.

Y por ultimo, el problema de origen es porque los 3 sistemas operativos principales(MAC OS X, Linux, Windows) manejan la codificación de diferente forma. Lo explica el enlace que puse.

Espero les sirva.
Saludos