us heu trobat mai que escriviu un text amb accents, dièresis, c trencades i d'altres caràcters que no siguin de l'estàndard ansi i que llavors es representin amb caràcters estranys?
això és degut al joc de caràcters (o charset en anglés), un altre aspecte a tenir en compte és la ordenació d'aquests caràcters (o collation en anglés)
introducció
com ja sabreu els caràcters es guarden a memòria com un conjunt de uns i zeros que al cap i a la fi seràn la representació binària de un número, doncs bé, els jocs de caràcters (UTF-8, ISO-8859-1, JIS, CP437) ens defineixen aquesta relació, a cada caràcter se li asigna un número (els famosos números de la taula ascii per exemple)
l'ordenació dels caràcters són regles amb les quals s'estableixen relacions entre els diferents símbols del joc de caràcters, així per exemple en un joc de caràcters amb 4 símbols ('a','b','A' i 'B') per saber si 'a' i 'b' són el mateix es miraria la codificació (el nº binari) dels símbols (les lletres) i s'establiria una relació de menor que, igual que o més gran que. Evidentment l'ordenació de qualsevol joc de caràcters és molt més complexe
per a cada joc de caràcters i ha múltiples ordenacions, però aquestes ordenacions son específiques del joc de caràcters, és a dir, si fas servir el joc de caràcters JIS (japonés) no pots fer servir una ordenació utf8_general_ci o una ordenació latin1_swedish_ci, apart que les aplicacions ja haurien de dir-te que no pots, les ordenacions o comparacions que faries tindrien resultats imprevisibles
exemples
quan nosaltres entrem un text aquest es guarda al disc traduit a números segons la codificació a la que treballi el nostre SO, escriptori, la base de dades on guardem les dades, el programa amb el que treballem, etc ... i a l'hora de representar aquestes dades també fem servir el joc de caràcters amb el que treballi el programa que ens el mostra
els problemes sorgeixen quan un fitxer guardat en un linux (la inmensa majoria de distribucions ja fan servir UTF-8) el veu un usuari de windows (latin1 o altrament dit ISO-8859-1 o -15 si és amb el símbol de l'euro), aquest veurá caràcters estranys, no se li farà el salt de línia (tot i que això ja és el format que fa servir cada S.O. per dir quan és el final de línia)
mysql
si ens centrem en les base de dades MySQL 4.1.x o 5.x (versions anteriors no permeten triar el joc de caràcters i l'ordenació) ens trobem amb un problema multiplicat per 5, perquè la gent de MySQL van decidir que poguessis determinar el joc de caràcters i l'ordenació d'aquests al servidor, la base de dades, la taula, cada camp de text i fins i tot la connexió!
ja a tall personal i vaig estar batallant molt de temps per aconseguir que la base de dades em treballés del tot amb UTF-8, fins que una bona lectura de tot el capítol 10 de la documentació del MySQL, em va fer veure la llum (si és que les documentacions ho solucionen tot, o casi)
si es vol treballar amb UTF-8 (o qualsevol altre codificació) a tots els nivells l'únic que hem de fer és posar en els nostres scripts php o (el llenguatge que sigui que interactua amb la base de dades) just després d'haver fet la connexió a la base de dades una sentència del tipus:
SET character_set_client=UTF8, character_set_connection=UTF8, character_set_database=UTF8,
character_set_results=UTF8, character_set_server=UTF8, character_set_system=UTF8;
hi ha un salt de línia per la formatació de la pàgina, seria tot seguit
i per les ordenacions:
SET collation_connection=utf8_general_ci, collation_database=utf8_general_ci, collation_server=utf8_general_ci;
les sentències SQL "SET" serveixen per modificar variables d'entorn del mysql, al executar una sentència d'aquest tipus li estàs dient "a partir d'ara tot el que et vingui li apliques aquestes variables d'entorn"
SET NAMES utf8;
per tant, és una bona idea posar aquestes sentències en el mateix script que facis la connexió, així segur que tot funcionarà tal i com ha d'anar (a no se que durant l'execució, pels motius que siguin, s'hagi de canviar de codificació) en aquest cas hauries de executarl la sentència "SET NAMES" abans de enviar-li els query's amb la nova codificació (o els paràmetres que hagis canviat) i tornar a deixar els que tenies abans (si es que interessa)
dir que hi han abreviatures per canviar-ho, però que no fan un canvi a totes les variables sinó només a unes quantes (se suposa que les que canvien son les necessàries, però fent-ho així segur que no hi ha cap error de codificació i segons com es miri el rendiment de la base de dades serà més alt perquè no tindrà d'estar perdent el temps canviant de joc de caràcters per anar a buscar i tornar els resultats)
tot i haver posat totes variables del MySQL a utf8 no vol dir que els teus formularis fets amb php et retornin les dades correctament, un cop resolta la base de dades el que falta és que el teu navegador també treballi amb utf8 i sobretot que també el php i treballi
php
per canviar el navegador, si fas servir firefox pots canviar-ho anant al menú Visualitzar->codificació de caràcters i allà tries UTF8 o la codificació que desitjis (apart si vas a les preferències pots definir un joc de caràcters per defecte)
per fer que els scripts amb php mostrin les pàgines amb php li pots enviar un header amb la línia següent:
header('Content-Type: text/html; charset=utf-8');
llavors ja només ens caldrà modificar el php.ini (fitxer de configuració del php) i afegir-hi les línies (pel mòdul iconv i exif):
busqueu i substituiu adeqüadament default_charset = "UTF-8" [exif] exif.encode_unicode = UTF-8 [iconv] iconv.input_encoding=UTF-8 iconv.output_encoding=UTF-8 iconv.internal_encoding=UTF-8
recordeu que perquè això funcion heu de compilar (o bé descarregar-vos els paquets) necessaris perquè el php doni suport al iconv i al exif (afegint --enable-exif i enable-iconv a la comanda de configuració del php ja n'hi haurà prou)
altre cop tenim una doble ventatja si els posem tots tres a UTF-8, ens assegurem de que treballarem a UTF-8 tot el temps i no hi haurà pèrdua en alguna conversió i augmentem el rendiment al no haver de fer que el php hagi d'anar canviant de joc de caràcters
teniu en compte que si per algun motiu o altre heu de tenir activat el mbstring us donarà problemes
Comentaris
Possibles problemes
Què passaria si s'indroduiren les dades des d'un navegador configurat amb una codifiació diferent (per exemple iso-8859-1, la codificació habitual).
És a dir: si faig un sistema de comentaris a la meva pàgina, i ho tinc tot funcionant amb utf-8 (php mysql i el meu navegador) com puc estar segur que el que escriguen els usuaris es tractarà correctament?
gràcies per preguntar! pots
gràcies per preguntar!
pots incloure un header al php i dir-li que sigui amb utf
header("Content-type: text/html; charset=utf-8");
pots incloure un meta-tag a la secció del "head"
meta http-equiv="Content-Type" content="text/html; charset=utf-8"
i també pots posar que en els formularis s'accepti un determinat joc de caràcters
form accpet-charset="utf-8" .....
i també tens funcions del php per passar textos a utf-8
Aleshores....
Gràcies per respondre tan prompte!
Aleshores si indique en el content-type (tant al header com amb meta) i en l'accept-charset del formulari que treballe amb utf-8, les dades m'arribaran en utf?
Si no és així, per a que aprofita el accept-charset del formulari?
home, en principi si que ha
home, en principi si que ha de ser així, que tu retorni amb utf, sinó seria una tonteria que tu permetessin, jo em referia a que alguns navegadors vells no deuen tenir implementat l'utf8 i llavors qui sap
pots fer un javascript que envii un comentari a l'usuari dient-li, però fes proves de quins navegadors van i quins no, mira si trobes alguna web que digui el suport dels navegadors
PHP i UTF-8
Aquest tema m'interessa molt, sobretot a PHP. Actualment tinc força problemes amb PHP i UTF-8. Tinc els script codificats com a UTF-8, però m'he adonat que les funcions de tractament de textos tenen problemes amb UTF-8.
Per exemple, aquest codi:
{codi}
echo iconv_get_encoding("internal_encoding");
$var = 'ADÉU';
echo $var = strtolower($var);
{/codi}
Retorna això:
{retorn}
UTF-8
ad?u
{/retorn}
Com pot ser? no em passa bé el text a minuscules si té accents! I tot està a UTF-8, l'arxiu PHP també, i envio un header amb:
header('content-type: text/html; charset=utf-8');
I el navegador està també amb UTF-8.
A php.ini tinc:
{php.ini}
[iconv]
iconv.input_encoding=UTF-8
iconv.output_encoding=UTF-8
iconv.internal_encoding=UTF-8
{/php.ini}
Tal com surt al article.
Algú em pot donar un cop de mà? Gràcies!
si faig un "cat
Faig servir Windows XP, no
Faig servir Windows XP, no sembla pas tenir cap problema amb UTF-8. Al php.ini hi tinc la secció de "iconv" bé, com també la de "exif". Però resulta que a Windows per a fer servir l'extenció php_exif.dll, cal tenir activada l'extenció php_mbstring.dll:
"Windows users must also have the mbstring extension enabled."
http://www.php.net/manual/es/ref.exif.php
Si activo la mbstring, puc fer servir les funcions mb_*(), amb les quals, si sembla funcionar el tractament amb cadenes de text, per exemple, mb_strtolower(). I això és el que no entenc, tothom qui fa págines multi-lingues, fa servir les funcions estàndard amb UTF-8, o les de mbstring?
He donat un cop d'ull al codi de alguns CMS coneguts, i tots els arxius PHP no estan pas codificats com a UTF-8. Com coi s'ho fan després per a poder ser traduits a un munt d'idiomes? :?
Per què a tu et funciones bé les funcions com strtolower() amb UTF-8, oi?
no cal pas
Bé, en realitat és al
Bé, en realitat és al revés, vull emprar strtolower() a un text UTF-8, però no hi ha manera. :-(
doncs no se :S tampoc ho se
La web del Gnome em surt
La web del Gnome em surt correcte, amb accents i "ç".
Em baixaré el PHP 5.0.5 que acava de sortir, a veure si canviant la versió i php.ini em funciona. :-?
Gràcies per les respostes!
uff el php5 canvia moooolta
He arribat a la conclusió,
He arribat a la conclusió, de que aquest comportament és normal. Les funcions "estàndards", són per a treballar amb codificacions d'un byte per caràcter. Tant se val si és Latin-1, com si és per a ciríl·lic o grec.
Però si es vol treballar amb text UTF-8, no queda més remei que fer-ho amb les funcions d'mbstring, (per això mateix és diu multi-byte).
Quant a PHP5, cap problema, fins ara feia servir una versió anterior de PHP5.
Un dia d'aquest potser em registro, però és que jo de tema wifi... poc puc aportar. :-(
doncs aporta al comesfa :P