Karakterkódolási problémák kiküszöbölése
Gyakori és visszatérő probléma, hogy valakinek meggyűlik a baja egy oldal készítése során a karakterkódolás témakörével, pedig ha pár apróságot betartunk, akkor nem lesz vele gondunk. A nehézséget valószínűleg az okozza, hogy a helyes működéshez több tényező megfelelő összehangolása szükséges, és ha bármelyikük rossz, akkor csak annyit tapasztalunk, hogy "nem megy jól az oldal". Ez a cikk igazából csak egy válasznak indult, de már korábban is szerettem volna írni erről a témáról, mert fontosnak érzem, hogy tisztázzuk ezt a kérdést, ezért végül úgy döntöttem, hogy egy kicsit jobban körüljárom a témát.
Mint a bevezetőben említettem, a probléma nem bonyolult, csak fontos, hogy kialakítsuk a helyes szemléletmódot. Ennek szerintem egyik fontos eleme, hogy ne csak kövessünk egy ajánlott receptet, hanem játszunk el a lehetőségekkel, jöjjünk tisztába azokkal a mechanizmusokkal, amiknek jelen esetben jelentősége van, különben hiba esetén nehezen fogunk tudni rájönni a megoldás kulcsára.
Először is következzen egy alap forgatókönyv, hogyan járjunk el, ha nulláról indulunk. Tegyük fel, hogy azt szeretnénk, hogy az oldalunk az ISO-8859-2 karakterkódolással működjön. A következő teendőink lesznek:
Ha ezekre figyel az ember, akkor alap esetben nem lesz gondja. Az alap esetet arra értem, hogy nem lesz gond, ha az űrlapjainkba tényleg
A gond akkor szokott kezdődni, amikor az ember azt tapasztalja, hogy nem jól jelennek meg a karakterek az oldalán (mert eredetileg nem a fentieknek megfelelően járt el), és kezdődik a kanosszajárás, ugyanis pl. a fenti leírásnak megfelelően elkezdi a különböző recepteket (ész nélkül) alkalmazni, és probléma mégsem akar megoldódni. ("Én már mindent beállítottam, de ...") Ilyenkor a hiba az, hogy úgy próbálunk meg javítani valamit, hogy nem győződünk meg a hiba okáról. Hiába kezdjük el kiadni mondjuk a megfelelő fejlécet, ha az adatbázisban rossz adatok vannak, vagy éppen a template fájljaink karakterkódolása más, mint amit használni szeretnénk. Hiába változtatjuk meg a tábla karakterkódolását, ha csatlakozáskor nem állítjuk be a megfelelő kliens oldal karakterkódolást, és az adatbázisból a tábla típus ellenére nem a számunkra kívánt formában kapjuk meg az adatokat. És még lehetne folytatni a sort, hogyan tudunk saját magunknak keresztbe tenni, és bosszúságot okozni, hogy ha nem szisztematikusan járunk el a hiba elhárítása érdekében.
Az ilyen esetekben nekem általában az a véleményem, hogy készítsünk egy apró teszt oldalt, ami semmi mást nem csinál, csak a problémás részre koncentrál. Gyakori eset, hogy egy hibakeresés azon bukik el, hogy igazából a hiba egy másik hiba mellékhatásaként jelentkezik, ezért nehezen találjuk meg az eredeti, teljes rendszerben. Fontos hogy ne feltételezésekből induljunk ki, hanem győződjünk meg a tényekről. Nagyon gyakori, amikor menetközben kiderül, hogy az a fránya fájl van rosszul kódolva, az az egy mező valamiért más karakterkódolást kapott, és így tovább.
Mint láttuk, nagyjából három dologra kell figyelni a helyes működés érdekében, ennek megfelelően ha hiba adódik, akkor ezen tényezőknek kell utána járnunk. A legegyszerűbb a megfelelő fejléc küldésének az ellenőrzése, amit könnyedén megtehetünk például a LiveHttpHeaders vagy a(z új kedvenc) TamperData nevű Firefox kiterjesztések használatával. Ha továbbra is fennáll a hiba, akkor mehetünk tovább, de figyeljünk arra, hogy amikor ellenőrizzük, hogy a változtatásaink jó működést eredményeznek-e, akkor "friss" adatokat használjunk, nehogy előforduljon az az eset, hogy már igazából minden jól van konfigurálva, csak az adatbázisban lévő, még a régebbi, rossz konfiguráció alatt felvitt adatok tréfálnak meg minket.
A hiba kijavítása során mindvégig legyünk nagyon alaposak, ez esetben fokozottan érvényes a "lassan jársz, tovább érsz" mondás. Nézzünk pár tipikus hibát:
Az egyik segítség egy
A másik mankónk a
Vizsgálódásom alapját a következő kérdések képezték:A script nagyon egyszerű, lehetőségünk van meghatározni az oldal kódlapját, majd pedig különböző
A következő táblázatok azt fogják tartalmazni, hogy az egyes böngészők adott beállítások és adott kódlapba tartozó input esetén milyen formátumban és kódlappal küldik a beírt adatokat a szervernek.Lássuk, hogy mit tudunk a fentiekből kihámozni. Az Explorer esetében az alapértelmezett kódlap az A Firefox esetében is az alapértelmezett kódlap az Az Opera teljesen úgy működik, mint a Firefox kivéve, hogy az alapértelmezett kódlap az én konfigomon az
A fentiek alapján láthatjuk, hogy ha az oldalunk
■ Mint a bevezetőben említettem, a probléma nem bonyolult, csak fontos, hogy kialakítsuk a helyes szemléletmódot. Ennek szerintem egyik fontos eleme, hogy ne csak kövessünk egy ajánlott receptet, hanem játszunk el a lehetőségekkel, jöjjünk tisztába azokkal a mechanizmusokkal, amiknek jelen esetben jelentősége van, különben hiba esetén nehezen fogunk tudni rájönni a megoldás kulcsára.
Először is következzen egy alap forgatókönyv, hogyan járjunk el, ha nulláról indulunk. Tegyük fel, hogy azt szeretnénk, hogy az oldalunk az ISO-8859-2 karakterkódolással működjön. A következő teendőink lesznek:
- Amennyiben adatbázist használunk, akkor állítsuk be úgy, hogy tábláink a megfelelő karakterkódolást használják. Itt érdemes figyelni arra, hogy pl. MySQL esetén lehetőség van mezőnként meghatározni, ezért ha valamilyen generáló eszközt használunk, akkor ellenőrizzük le, hogy a mezőink tényleg az általunk kívánt beállítással jöttek létre.
- Legyenek a PHP fájljaink is ilyen kódolásúak, illetve nem is feltétlenül mind, hanem azok a fájlok, amik a kimenetben is megjelenő szövegeket tartalmaznak, és persze ez szintén vonatkozik a template állományainkra.
- A HTML kódban szerepelhet meta tagként is az adott kódolás, de ez nem annyira fontos, de az igen, hogy az oldal megfelelő
Content-Type
fejléccel legyen kiszolgálva, annakcharset
paramétere az általunk választott kódolást tartalmazza. Ezzel lehetne vitatkozni annyiban, hogy elég a meta tag, ha nincs ezzel ellentétes tartalmú fejléc, de ha mi kiadjuk a megfelelőt, akkor nem fogunk kétes szerver beállításoktól függeni.
- Ezután már csak arra kell figyelnünk, hogy az adatbázissal történő kommunikációnk során biztosítsuk, hogy a szerver a számára küldött parancsokat az általunk használt karakterkódolásnak megfelelően értelmezze. Ezt pl. MySQL használata esetén a
SET NAMES latin2
parancs kiadásával érhetjük el.
Ha ezekre figyel az ember, akkor alap esetben nem lesz gondja. Az alap esetet arra értem, hogy nem lesz gond, ha az űrlapjainkba tényleg
latin2
kódolású szövegeket írnak be. Ha mégis ez történik, akkor nem árt ha van nálunk egy kevés friss kakas vér, mert ugyan van lehetőségünk befolyásolni (_charset_, accept-charset), hogy a böngészők hogyan reagáljanak erre az esetre, de hogy ténylegesen mi fog történni, az eléggé megvalósítás függő.A gond akkor szokott kezdődni, amikor az ember azt tapasztalja, hogy nem jól jelennek meg a karakterek az oldalán (mert eredetileg nem a fentieknek megfelelően járt el), és kezdődik a kanosszajárás, ugyanis pl. a fenti leírásnak megfelelően elkezdi a különböző recepteket (ész nélkül) alkalmazni, és probléma mégsem akar megoldódni. ("Én már mindent beállítottam, de ...") Ilyenkor a hiba az, hogy úgy próbálunk meg javítani valamit, hogy nem győződünk meg a hiba okáról. Hiába kezdjük el kiadni mondjuk a megfelelő fejlécet, ha az adatbázisban rossz adatok vannak, vagy éppen a template fájljaink karakterkódolása más, mint amit használni szeretnénk. Hiába változtatjuk meg a tábla karakterkódolását, ha csatlakozáskor nem állítjuk be a megfelelő kliens oldal karakterkódolást, és az adatbázisból a tábla típus ellenére nem a számunkra kívánt formában kapjuk meg az adatokat. És még lehetne folytatni a sort, hogyan tudunk saját magunknak keresztbe tenni, és bosszúságot okozni, hogy ha nem szisztematikusan járunk el a hiba elhárítása érdekében.
Az ilyen esetekben nekem általában az a véleményem, hogy készítsünk egy apró teszt oldalt, ami semmi mást nem csinál, csak a problémás részre koncentrál. Gyakori eset, hogy egy hibakeresés azon bukik el, hogy igazából a hiba egy másik hiba mellékhatásaként jelentkezik, ezért nehezen találjuk meg az eredeti, teljes rendszerben. Fontos hogy ne feltételezésekből induljunk ki, hanem győződjünk meg a tényekről. Nagyon gyakori, amikor menetközben kiderül, hogy az a fránya fájl van rosszul kódolva, az az egy mező valamiért más karakterkódolást kapott, és így tovább.
Mint láttuk, nagyjából három dologra kell figyelni a helyes működés érdekében, ennek megfelelően ha hiba adódik, akkor ezen tényezőknek kell utána járnunk. A legegyszerűbb a megfelelő fejléc küldésének az ellenőrzése, amit könnyedén megtehetünk például a LiveHttpHeaders vagy a(z új kedvenc) TamperData nevű Firefox kiterjesztések használatával. Ha továbbra is fennáll a hiba, akkor mehetünk tovább, de figyeljünk arra, hogy amikor ellenőrizzük, hogy a változtatásaink jó működést eredményeznek-e, akkor "friss" adatokat használjunk, nehogy előforduljon az az eset, hogy már igazából minden jól van konfigurálva, csak az adatbázisban lévő, még a régebbi, rossz konfiguráció alatt felvitt adatok tréfálnak meg minket.
A hiba kijavítása során mindvégig legyünk nagyon alaposak, ez esetben fokozottan érvényes a "lassan jársz, tovább érsz" mondás. Nézzünk pár tipikus hibát:
- "A böngészőben jól jelenik meg, de ha a DB-ben nézem, akkor mindenféle kirksz-krakszok vannak." Ez jellemzően akkor fordul elő, amikor nem adunk ki egy űrlap esetén megfelelő fejlécet (pl. egy magyar oldal esetén nincs vagy
latin1
), ezért a böngésző bizonyos ékezetes karaktereket HTML entity-ként küld el a szervernek, vagy pl. Internet Explorer esetén egy másik, tetszőlegesen választott karakterkódolást használva.
- "Az adatbázisban biztosan jók az adatok, mert ilyen-olyan kliensben jól jelenik meg." Fontos, hogy meggyőződjünk arról, hogy tényleg milyen formában van letárolva az adat. Például a MySQL automatikusan konvertálja az adatokat a kliens (jelen esetben a PHP) karakterkódolása és az adott mező tényleges karakterkódolása között.
- "Minden jól be van állítva, a mező is latin2, a fejléc is latin2, mégis eltűnik az ő, ű betű." Na ez itt már egy érdekesebb téma. Amikor a PHP-ból kapcsolódunk a MySQL-hez, akkor alap esetben a kliens oldali karakterkódolás a szerver alapértelmezett karakterkódolása lesz, ami többnyire latin1 szokott lenni, hacsak külön nem állítják át egy másik értékre. Kapcsolódik a PHP, a
character_set_client
latin1 lesz. Beszúrjuk szépen a böngészőből kapott latin2-es szöveget, de a MySQL úgy tudja, hogy mi latin1-et fogunk neki adni, ezért elcsodálkozik az ő, ű karakteren, és mivel ilyen nincs a latin1-ben, ezért lecseréli őket. Ennek elkerülése végett célszerű kiadni aSET NAMES latin2
parancsot, így alkalmazásunk függetlenné válik az éppen használt MySQL szerver beállításaitól.
_charset_, accept_charset
Fentebb már szóba került, hogy külön kezelnünk kell azt az esetet, amikor a felhasználó az oldalunkon szereplő űrlapba olyan karaktert ír be, amely nem szerepel az oldalunkhoz rendelt kódlapban. Először is lássuk, hogy a különböző böngészők mit is tesznek ebben az esetben. A Firefox és Opera úgy jár el, hogy az adott kódtáblában nem megtalálható karaketereket lecseréli azok NCR megfelelőjére, az Internet Explorer ezzel szemben önkéntesen megváltoztatja az elküldendő adatok karakterkódolását, és abban a formában küldi az adatokat. Ezt követően nézzük, hogy egyáltalán milyen mankókat használhatunk az ilyen esetek elleni védekezéshez.Az egyik segítség egy
_charset_
nevű rejtett input mező elhelyzése az úrlapon, melyben a böngésző (amennyiben támogatja ezt a módszert) jelzi, hogy valójában milyen karakterkódolású is a küldött adat. Jelenleg mindhárom a cikkben már említett böngésző támogtja ezt, valamint ez a megoldás a Web Froms 2.0 ajanlás része is. Ha például Internet Explorer alatt nem határozom meg az oldal karakterkódolását, akkor ha az elküldött adat az "abc" szöveg, akkor a _charset_
értéke ISO-8859-1
lesz, de ha már tartalmaz a szöveg mondjuk egy ő betűt, akkor Windows-1250
. A fentiek fényében használhtajuk ezt az értéket arra, hogy a kapott adatot az általunk használt kódtáblára konvertáljuk. Egy több országban futó oldal esetén például az volt a tapasztalat, hogy hiába fért bele az összes érintett nyelv minden karaktere a használt kódlapba, mégis néha előfordult, hogy az Explorer kódlapot váltott (valószínűleg copy-paste szövegek esetén), és ilyenkor nagy segítség volt az _charset_
által nyújtott információ.A másik mankónk a
form
tag accept-charset
attribútuma. Ebben azt tudjuk jelezni a böngésző számára, hogy szerver oldali űrlap feldolgozó scriptünk milyen karakterkódolásokat képes kezelni. Hmm, miért hasznos ez számunkra? Mindjárt látni fogjuk részletesen, de előzetesen annyit, hogy ha itt megadunk egy karakterkódolást, akkor a böngészőknek ezt kéne használni az adatok küldésekor szemben az oldal számára megadottal. Azért írtam, hogy kéne, mert a vizsgált böngészők közül az Internet Explorer ezúttal is tartogat számunkra némi meglepetést.Vizsgálódásom alapját a következő kérdések képezték:
- Mi az adott böngésző esetén az alapértelmezett kódlap?
- Mi történik, ha olyan karaktert ütök le, amely része az oldal kódlapjának?
- Mi történik, ha olyan karaktert ütök le, amely nem része az oldal kódlapjának?
- Mi történik, az előző esetben, ha van accept_charset megadva, és az érintett karakter része az itt megadott kódlapnak?
- Mi történik, az előző előtti esetben, ha van accept_charset megadva, de az érintett karakter nem része az itt megadott kódlapnak?
<?php
session_start();
if (isset($_GET['charset'])) {
$_SESSION['charset'] = $_GET['charset'];
}
if (!empty($_SESSION['charset'])) {
header('Content-Type: text/html; charset='.$_SESSION['charset']);
echo 'Current charset: '.$_SESSION['charset'].'<br>';
}
?>
Set charset to:
<a href="?charset=ISO-8859-1">ISO-8859-1</a>
<a href="?charset=ISO-8859-2">ISO-8859-2</a>
<a href="?charset=UTF-8">UTF-8</a>
<a href="?charset=0">none</a>
<br><br>
accept-charset="UTF-8"
<form method="post" accept-charset="UTF-8">
<input type="hidden" name="_charset_">
<input name="text" size="1" maxlength="1">
<input type="submit">
</form>
accept-charset="iso-8859-2"
<form method="post" accept-charset="iso-8859-2">
<input type="hidden" name="_charset_">
<input name="text" size="1" maxlength="1">
<input type="submit">
</form>
accept-charset=none
<form method="post">
<input type="hidden" name="_charset_">
<input name="text" size="1" maxlength="1">
<input type="submit">
</form>
Latin1: »<br>
Latin2: ť<br>
Latin3: ğ<br>
<br>
<?php
if (!empty($_POST)) {
echo '_charset_: '.$_POST['_charset_'].'<br>';
echo 'text: '.$_POST['text'].'<br>';
echo 'text.type: '.(strlen($_POST['text']) == 6 ? 'NCR':'CHAR').'<br>';
}
?>
accept-charset
beállítások mellett karaktereket küldeni feldolgozásra. Ebben az esetben a script kiírja az _charset_
változó értékét, valamint jelzi, hogy a böngésző karaktert vagy NCR-t küldött-e. Ezenkívül még megjelenít három karaktert, melyeket billentyűzetről nehezen tudnánk bevinni az input mezőbe, de így könnyedén kijelölhetőek és beilleszthetőek. Ezek jelentősége, hogy a mellettük szereplő kódlapban azonos az értékük, és mindegyiküket csak az adott kódlap tartalmazza, így jó alanyai lesznek a tesztelésnek. A következő táblázatok azt fogják tartalmazni, hogy az egyes böngészők adott beállítások és adott kódlapba tartozó input esetén milyen formátumban és kódlappal küldik a beírt adatokat a szervernek.
Internet Explorer
+----------------------------------------------------------------------------+
| | accept_charset attribútum értéke |
| |------------------------------------------|
| | nincs | ISO-8859-1 | UTF-8 |
|---------------------------------+--------------+--------------+------------|
| | | | ISO-8859-1 | CHAR | CHAR | CHAR |
| | | i | | ISO-8859-1 | ISO-8859-1 | ISO-8859-1 |
| | | n |------------+--------------+--------------+------------|
| | nincs | p | ISO-8859-2 | CHAR | CHAR | CHAR |
| | | u | | Windows-1250 | Windows-1250 | UTF-8 |
| | | t |------------+--------------+--------------+------------|
| | | | ISO-8859-3 | CHAR | CHAR | CHAR |
| | | | | Windows-1254 | Windows-1254 | UTF-8 |
| |------------+---+------------+--------------+--------------+------------|
| K | | | ISO-8859-1 | CHAR | CHAR | CHAR |
| a | | i | | ISO-8859-1 | ISO-8859-1 | ISO-8859-1 |
| r | | n |------------+--------------+--------------+------------|
| a | ISO-8859-1 | p | ISO-8859-2 | CHAR | CHAR | CHAR |
| k | | u | | Windows-1250 | Windows-1250 | UTF-8 |
| t | | t |------------+--------------+--------------+------------|
| e | | | ISO-8859-3 | CHAR | CHAR | CHAR |
| r | | | | Windows-1254 | Windows-1254 | UTF-8 |
| |------------+---+------------+--------------+--------------+------------|
| k | | | ISO-8859-1 | CHAR | CHAR | CHAR |
| ó | | i | | Windows-1252 | Windows-1252 | UTF-8 |
| d | | n |------------+--------------+--------------+------------|
| o | ISO-8859-2 | p | ISO-8859-2 | CHAR | CHAR | CHAR |
| l | | u | | ISO-8859-2 | ISO-8859-2 | ISO-8859-2 |
| á | | t |------------+--------------+--------------+------------|
| s | | | ISO-8859-3 | CHAR | CHAR | CHAR |
| | | | | Windows-1254 | Windows-1254 | UTF-8 |
| |------------+---+------------+--------------+--------------+------------|
| | | | ISO-8859-1 | CHAR | CHAR | CHAR |
| | | i | | UTF-8 | UTF-8 | UTF-8 |
| | | n |------------+--------------+--------------+------------|
| | UTF-8 | p | ISO-8859-2 | CHAR | CHAR | CHAR |
| | | u | | UTF-8 | UTF-8 | UTF-8 |
| | | t |------------+--------------+--------------+------------|
| | | | ISO-8859-3 | CHAR | CHAR | CHAR |
| | | | | UTF-8 | UTF-8 | UTF-8 |
+----------------------------------------------------------------------------+
ISO-8859-1
(pedig a területi beállításom magyar). A küldendő karakterek szempontjából azt a logikát követi, hogy ha az nem fér bele az oldal kódlapjába, akkor megpróbál találni egy olyan kódlapot, amelynek része, és ebben küldi el. Amennyiben nem talál ilyet, akkor elvileg ő is NCR-t küld, de ezt az esetet nem sikerült kikényszeríteni belőle. Az accept_charset
kezelése elég sajátos a másik két böngésző viselkedéséhez képest. Egyrészről fura, hogy bizonyos esetekben figyelembe veszi azt, máskor nem. Ha például egy ISO-8859-1
-es oldalunk van, amin egy ISO-8859-2
-es karaktert próbálunk küldeni, akkor ha megnézzük a táblázatot, azt látjuk, hogy az accept_charset
ISO-8859-2
-es értéke esetén a Windows-1250
-es kódlapot választja, viszont az UTF-8
-as értéket már figyelembe veszi, és azt használja. Másrészről azzal a felfogással is lehet vitatkozni, hogy ha a beírt karakter belefér az oldal kódlapjába, akkor teljes mértékben figyelmen kívül hagyja az accept_charset
beállítást, hiszen ez azt mondja meg, hogy a fogadó script milyen kódolásokat képes megérteni, és egyáltalán nem biztos, hogy ennek összhangban kell lennie az oldal kódlapjával (pl. egy magyar oldalról adatokat küldünk egy angol oldalnak). Firefox
+--------------------------------------------------------------------+
| | accept_charset attribútum értéke |
| |----------------------------------|
| | nincs | ISO-8859-1 | UTF-8 |
|---------------------------------+-------------+------------+-------|
| | | | ISO-8859-1 | CHAR | NCR | CHAR |
| | | i | | ISO-8859-1 | ISO-8859-2 | UTF-8 |
| | | n |------------+-------------+------------+-------|
| | nincs | p | ISO-8859-2 | NCR | CHAR | CHAR |
| | | u | | ISO-8859-1 | ISO-8859-2 | UTF-8 |
| | | t |------------+-------------+------------+-------|
| | | | ISO-8859-3 | NCR | NCR | CHAR |
| | | | | ISO-8859-1 | ISO-8859-2 | UTF-8 |
| |------------+---+------------+-------------+------------+-------|
| K | | | ISO-8859-1 | CHAR | NCR | CHAR |
| a | | i | | ISO-8859-1 | ISO-8859-2 | UTF-8 |
| r | | n |------------+-------------+------------+-------|
| a | ISO-8859-1 | p | ISO-8859-2 | NCR | CHAR | CHAR |
| k | | u | | ISO-8859-1 | ISO-8859-2 | UTF-8 |
| t | | t |------------+-------------+------------+-------|
| e | | | ISO-8859-3 | NCR | NCR | CHAR |
| r | | | | ISO-8859-1 | ISO-8859-2 | UTF-8 |
| |------------+---+------------+-------------+------------+-------|
| k | | | ISO-8859-1 | NCR | NCR | CHAR |
| ó | | i | | ISO-8859-2 | ISO-8859-2 | UTF-8 |
| d | | n |------------+-------------+------------+-------|
| o | ISO-8859-2 | p | ISO-8859-2 | CHAR | CHAR | CHAR |
| l | | u | | ISO-8859-2 | ISO-8859-2 | UTF-8 |
| á | | t |------------+-------------+------------+-------|
| s | | | ISO-8859-3 | NCR | NCR | CHAR |
| | | | | ISO-8859-2 | ISO-8859-2 | UTF-8 |
| |------------+---+------------+-------------+------------+-------|
| | | | ISO-8859-1 | CHAR | NCR | CHAR |
| | | i | | UTF-8 | ISO-8859-2 | UTF-8 |
| | | n |------------+-------------+------------+-------|
| | UTF-8 | p | ISO-8859-2 | CHAR | CHAR | CHAR |
| | | u | | UTF-8 | ISO-8859-2 | UTF-8 |
| | | t |------------+-------------+------------+-------|
| | | | ISO-8859-3 | CHAR | NCR | CHAR |
| | | | | UTF-8 | ISO-8859-2 | UTF-8 |
+--------------------------------------------------------------------+
ISO-8859-1
. A karakterek küldésének kezelése letisztultabbnak és logikusabbnak mondható. Ha adtunk meg accept_charset
-et, akkor abban a kódlapban próbálja meg elküldeni az adatokat, ha nem akkor az oldaléban. És bármely esetben ha a karakter nem fér bele az érintett kódlapba, akkor helyette a böngésző NCR-t küld. Opera
+--------------------------------------------------------------------+
| | accept_charset attribútum értéke |
| |----------------------------------|
| | nincs | ISO-8859-1 | UTF-8 |
|---------------------------------+-------------+------------+-------|
| | | | ISO-8859-1 | NCR | NCR | CHAR |
| | | i | | ISO-8859-2 | ISO-8859-2 | UTF-8 |
| | | n |------------+-------------+------------+-------|
| | nincs | p | ISO-8859-2 | CHAR | CHAR | CHAR |
| | | u | | ISO-8859-2 | ISO-8859-2 | UTF-8 |
| | | t |------------+-------------+------------+-------|
| | | | ISO-8859-3 | NCR | NCR | CHAR |
| | | | | ISO-8859-2 | ISO-8859-2 | UTF-8 |
| |------------+---+------------+-------------+------------+-------|
| K | | | ISO-8859-1 | CHAR | NCR | CHAR |
| a | | i | | ISO-8859-1 | ISO-8859-2 | UTF-8 |
| r | | n |------------+-------------+------------+-------|
| a | ISO-8859-1 | p | ISO-8859-2 | NCR | CHAR | CHAR |
| k | | u | | ISO-8859-1 | ISO-8859-2 | UTF-8 |
| t | | t |------------+-------------+------------+-------|
| e | | | ISO-8859-3 | NCR | NCR | CHAR |
| r | | | | ISO-8859-1 | ISO-8859-2 | UTF-8 |
| |------------+---+------------+-------------+------------+-------|
| k | | | ISO-8859-1 | NCR | NCR | CHAR |
| ó | | i | | ISO-8859-2 | ISO-8859-2 | UTF-8 |
| d | | n |------------+-------------+------------+-------|
| o | ISO-8859-2 | p | ISO-8859-2 | CHAR | CHAR | CHAR |
| l | | u | | ISO-8859-2 | ISO-8859-2 | UTF-8 |
| á | | t |------------+-------------+------------+-------|
| s | | | ISO-8859-3 | NCR | NCR | CHAR |
| | | | | ISO-8859-2 | ISO-8859-2 | UTF-8 |
| |------------+---+------------+-------------+------------+-------|
| | | | ISO-8859-1 | CHAR | NCR | CHAR |
| | | i | | UTF-8 | ISO-8859-2 | UTF-8 |
| | | n |------------+-------------+------------+-------|
| | UTF-8 | p | ISO-8859-2 | CHAR | CHAR | CHAR |
| | | u | | UTF-8 | ISO-8859-2 | UTF-8 |
| | | t |------------+-------------+------------+-------|
| | | | ISO-8859-3 | CHAR | NCR | CHAR |
| | | | | UTF-8 | ISO-8859-2 | UTF-8 |
+--------------------------------------------------------------------+
ISO-8859-2
.A fentiek alapján láthatjuk, hogy ha az oldalunk
UTF-8
kódolást használ, akkor sok gondunk nincs, ellenkező esetben viszont érdemes valamilyen stratégiát kialakítanunk a problémás esetek kezelésére. Döntésünk meghozatalakor még azt vegyük figyelembe, hogy lehetőleg kerüljük azokat az eseteket, amikor NCR-eket kaphatunk vissza, ugyanis ezekkel van egy komoly gond: nem tudjuk eldönteni, hogy egy NCR azért szerepel a szövegben, mert a böngésző helyezte el benne egy problémás karaktert lecserélve, vagy pedig ténylegesen része kéne legyen a szövegnek. Hogy ez jobban érthető legyen: mind az "őő", mind az "őő" input alapján a szerverre "őő" fog megérkezni, és nem tudjuk eldönteni, hogy a felhasználó mit is gépelt be. Ezen információk fényében én azt javaslom, hogy amennyiben nem UTF-8
az oldalunk kódolása, akkor helyezzünk el egy _charset_
nevű rejtett input elemet űrlapjainkon, és állítsuk be az accept_charset
attribútumot UTF-8
-ra, és a bejövő adatokon a kapott _charset_
érték alapján szükség esetén végezzük el a számunkra megfelelő konverziót (például az iconv PHP kiterjesztés segítségével).
hibás cím
Szerk.: meg a kanosszajárás is.
köszi, javítva
IE és az UTF-8 oldal esete
Lenne egy kis gondom egy weblappal kapcsolatban, amit sehogyan sem tudtam eddig megoldani ...
Van egy html oldalam és van három különböző teszt számítógépem IE-vel, az egyiken Firefoxszal is.
A weblap a három gép közül az egyiken (IE6) azt csinálja, hogy letöltődik, és a utf-8 header (elmentve is így van persze) ellenére rossz kódlappal jelenik meg. Megnyomom a Refresh-t a böngészőn, akkor helyreáll és jó egészen addig, míg ki nem törlöm a helyben tárolt tartalmat. Akkor legközelebb elsőre megint rosszul töltődik le....a másik kettő gépen viszont ezt nem csinálja, mindenképpen jó.
Mivel a három gép közül csak az egyiken csinálja ezt, ezért gondolom hogy az alapvető hiba nem weblappal lehet.
Hanem azt lenne jó tudni, hogy akkor hol lehet a gubanc, ha élesben fog menni a weboldal akkor vajon a felhasználók mekkora része fogja úgy látni, hogy egy ócska, olvashatatlan oldalra tévedt?....Milyen beállítástól vagy komponenstől függhet, amit talán ellenőrizni is tudnék hogy megvan-e, megfelelő-e, mint ahogyan most pl. a Javascripttel is teszem...
Ha volna valakinek ötlete, hogy hol kellene keresgélni, annak örülnék...
Közben sikerült kitalálnom !
Rájöttem közben!
Nálam akkor jelentkezik ez a hiba, ha az oldal HEAD-jében nincs Language META tag ÉS az Explorerben a Jobb gomb->Kódolás menüben be van pipálva az Automatikus választás.
Ha a pipa nincs ott, akkor az oldal elsőre is jól jön le.
Illetve én beletettem az oldalba eg ilyen TAG-et:
<META HTTP-EQUIV="Content-Language" CONTENT="en-GB">
és ezután már jól műxik ha van pipa ha nincs. Magyar lang beállítással nem próbáltam az még hátra van.
Üdv !
3 apróság
2. IE "táblázat" után a kikényszeríteni szóból kimaradt egy karakter
3. a "táblázatokat" lehetne rendes táblázatként beszúrni a szövegbe? Nagyon átláthatlannak és csúnyának találom őket így...
re: 3 apróság
Véleményes, láttam elég gyakran mindkét formában.
Köszi, javítva.
Ezek kicsit komplex táblázatok, nem sikerült bbcode-dal rowspant és colspant megadni, ezért jött a lynx feeling, de simán weboldalon is szinte teljesen így néz ki.
Az értelmezése meg szerintem adja magát (bár lehet, hogy csak azért, mert sokat bíbelődtem vele ;)), szinte olvashatod balról jobbra: x karakterkódolású oldalon jön inputként egy x kódlapban lévő karakter, aminek a hatására a böngésző az űrlap
accept-charset
beállítása függvényében adott formában küldi az adatot.Felhő
Gratula a cikkhez!
Úgy látom érdemes volt kikönyörögnöm ezt a parancssoros "színezést", ha ti is szívesen használjátok. Szerintem semmi baj ezekkel a táblázatokkal. Nem szép színes, de legalább átlátható.
Köszönöm
üdv,
Feri
Internet Explorer 7 Release Candidate 1 in standalone mode
ui: persze köszönet a cikkért :) (crossForm-om nevében is :)) )
Köszönjük!
(nemrég sokat szenvedtem latin2 <-> UTF-8 vegyesfelvágottban írt egész nagy rendszeren, aminek UTF-8at kellett kiadnia. Mennyivel egyszerűbb most dolgozni vele, hogy minden UTF-8as. DE igazából mindegy, hogy UTF8, avagy Latin2, csak egyforma legyen)
UTF-8 Rulez!
rage
utöfö nyóc
v.jani
he?
Vagy ha igen:
Ha nem nagyon vigéckedsz a PHP fájlodban a speciális karakterekkel, akkor az esetek 99%-ban nincs gondod az UTF kódolással. A maradékra meg ott vannak az mb_* fgv-nyek.
A másik esetben nem a delphivel van a probléma. :D Hanem a windows-zal és azokkal a kontrollokkal, komponensekkel, amiket a Microsoft csinált. Ugyanis a windows alapállapotban nem nagyon kezeli az unicode-ot, csak kiegészítőkkel, vérrel és verítékkel. Amúgy is az MS nyelv- és kódolástámogatása egy szép nagy vicc.
De a delphi-hez is le tudsz tölteni kontrol-okat, amik unicode-osak, keress rá a TNT csomagra. Egész jó cucc, én használom. :)
Ráadásként: az UTF és az Unicode szép és átlátható. Semmi mágia nincs benne. Az, hogy a megvalósításokkal sok helyen gond van, nos az informatika mindig is ilyen volt. :D Sosem ment semmi elsőre flottul. :) Csak idő kérdése, már nincs olyan messze az UTF-es, register_globals-mentes PHP6. Addig meg igyunk meg még egy sört.... :D
Segítséget szeretnék
Nekem az a problémám, hogy localhost-on az "ő" betűt nem jeleníti meg. Egyenlőre csak adatbázisból jelenít meg adatokat. Próbáltam utf-8-ban is, iso-8859-2-ben is, MySQL-ben és a meta információknál is ugyanarra állítottam, de nem akarja az igazságot. Próbáltam Firefoxban is állítani a karakterkódolást.
Felraktam az oldalt uw-ra, onnan tökéletesen megy.
Van valami tippetek?
szisztematikus hibakeresés
El kéne olvasd még egyszer figyelmesen a cikket. Pont ezt próbáltam meg kiemelni, hogy ne csak nekiálljunk állítgatni a dolgokat, hanem előbb győződjünk meg a tényekről. Másodsorban kód nélkül semmit sem tudunk csinálni. Mielőtt elkéred a DB-ből az adatokat, kérdezd le, hogy mi a kliens oldali karakterkódolás. Ellenőrizd a böngészőben, hogy a megfelelő fejlécet adod-e ki, hogy nem a szövegek a DB-ben hibásak (lásd a cikkben a friss adatok használatára történő utalást).
Felhő
thx
Azért kössz.
sikerült
Kicsit nehezen értelmeztem elsőre a cikkben írtakat, az lehetett a probléma :)
UTF-8
Jelenleg minden fájlom UTF-8
Az adatbázisban is minden utf8/utf8_hungarian_ci
my.ini: default-character-set=utf8
php.ini: default-charset: kikommentezve
Mégis kérdőjelek jelennek meg az ékezetek helyett:(
Csak PHP-ban. MySql managerben jól jeleníti meg.
meg van a megoldás:)
Ezért a mysql user-től vonjuk meg ezt a jogosultságot, és már megy is!
Üdv Karesz
utf8_general_ci / ut8_hungarian_ci
general vs. hungarian
A general az csak simán kód szerint (így a–z elébb jön, mint á, å, ð, ő, azok pedig előbb, mint б, ц, ก, น…), a hungarian pedig a magyar rendezési elvek szerint: aá b c cs d dz dzs eé f g gy h ií j k l ly m n ny oó öő p q r s sz t ty uú üű v w x y z zs
ismeretlen kodolas identifikacio
dekodolasnal nincs biztonsag
Ez az alap.
De, elég jó hatásfokot lehet elérni ezekkel a fgv-ekkel (http://php.net):
iconv vagy mb_convert_encoding. Nézz utána.
MyAdmin vicces kedvű
Köszönet
Z
ISO-8859-1
LOL
kérdés
miért? valamit nem olvastam el? köszönöm!
mivel mented el?
iso-8859-2
Biztosra nem mondanám, hogy nem lehet itt "header("Content-Type: text/html; charset=latin2");" latin2-t mondani, de az biztos, hogy mindig azt láttam, hogy itt ilyen formában adják meg: iso-8859-2. Meg kéne próbálnod kicserélni. Plusz amikor az oldal bejön a böngészőbe, akkor a böngésző milyen encodingot választ?
Üdv,
Felhő
jeje:)
1. headerben elfogadja a latin2-t, és a iso-8859-2-vel is műxik.
2. megnéztem a lap encodingját, Középeurópai ISOra raktam de ha jól emléxem DWben ez az alap beállítás és most nem emlékszem de szerintem ezen volt:S
3. most viszont ezt írta ki: Data too long for column 'nev' at row 1
kiszedtem belőle a mysql_query("SET NAMES latin2"); sort és most megy rendesen.
A MySQL query browserben most 'hegedus'-ből 'heged|s' lett. jó ez így? lekérdezésnél szépen kiírja a lapra az ékezeteket, szóval csak a progi nem kezeli ezeket az ékezeteket megfelelően?
Köszönöm mindkettőtöknek a segítséget, tanultam vmit!:)
Szerk: 5 db most szót használtam!:)))
UI: JAJJ lenne még egy kérdésem!! MySQL! MySQL ADMIN toolsban létrehoztam egy felhasználót, de hogy tudok neki adatbázis létrehozó jogot adni? Nem adatbázison belül táblát! Adatbázist! Azt csak root tud? Mert a jogokkal kapcsolatos részt megtaláltam, szépen rá kell húzni a jogosultságokat az adatbázisokra, nade adatbázis létrehozás jog nincs és azt hova is húznám ugye... előre is köszi!
Sehogy se akarja...
Adott egy excel tábla, ebből utf-8-cal exportáltam csv-be a tartalmat. Ezt a csv-t egy saját szkripttel (utf-8) átírtam sql insertekké.
Létrehoztam a táblát MySql-ben (MySQL alap karakterkészlet utf-8, MySql kapcsolat egyeztetés utf-8_unicode_ci), itt a tábla egybevetése utf-8_hungarian_ci és a mezőké is. Mind a http fejléc, mind a meta tag phpMyAdminban utf-8-as, itt rendesen is jelenik meg.
Az oldalon kiolvasom a tábla tartalmát (a szkript utf-8-as itt is), utf-8-as Content-type-pal kiküldöm. Meghívok egy mysql_query("SET NAMES utf-8");-at , Firefox>Nézet>Karakterkódolás>UNICODE(UTF-8).
Az adatbázisból kiolvasott szöveg pedig rombuszos kérdőjelekkel jelenik meg. A rókában való kísérletezés után kiderül, hogy ezek a szövegek latin2-esek.
Bocs a terjengősségért, igyekeztem minden körülményt megadni. Van bárkinek ötlete, mit nem állítottam be?
Szerk.: Érdekes, az IE (UTF-8-as beállítással) jól jeleníti meg (Opera megint csak hibás.)
SET NAMES 'utf8' !
Szerintem az a hiba, hogy itt ha jól tudom nem kötőjellel, hanem anélkül kell megadni, hogy utf8:
Re: SET NAMES 'utf8' !
kösz
SET NAMES latin2
Habár még nem volt időm végigolvasni az egész cikket, egy évvel ezelőtti emlékeim szerint ez a parancs csak és kizárólag az új MySQL-eken ment (új alatt értsd, hogy akkoriban még elterjedt volt az a verzió amin nem ment), ami nem teljesen elhanyagolható szerintem.
Nekem ez jött be,amikor
$karakter_mire = array("á","Á","é","É","ö","Ö","õ","Õ",
"ü","Ü","û","Û","í","Í","ó","Ó");
$_POST['szoveg']=str_replace($karakter_mit, $karakter_mire,$_POST['szoveg'] );
Sziasztok!Hozzászólások elég
Hozzászólások elég régiek, de nekem most aktuális ez a téma. Reménykedek benne, hogy kapok segítséget.
A tudásom nem tökéletes, ellenben nagy a szorgalmam.
Ha jól értem három dologra kell odafigyelni egy egyszerű /adatbázis használata nélküli/oldal elkészítéséhez:
valami.php fájlt utf-8 kódolással írjam
meta tageknél a charset-et is utf-8-ra állítani
header('Content-type: text/html; charset=utf-8');
header() fgv-nél is ugyan így járok el. Erről tudom, hogy még akkor kell meghívni mielőtt bármi is történne a honlapunkkal.
A következő php kód, amiben szeretném, ha tanácsod adnátok:
index.php
Már megy az oldal és pont a főnök szembesült elsőnek a problémámmal.
Kérlek segítsetek!
uj tema