apache, php, mysql és utf-8 debian sarge-on

Aki már készített weboldalt, biztosan találkozott azokkal a problémákkal, amelyek édes magyar anyanyelvünk, pontosabban ékezetes karaktereinek megjelenítése, tárolása, kezelése okozott. További problémák pedig akkor szoktak jelentkezni, ha egy weblapnak több nyelven is szólnia kell a látogatóhoz. Itt nem az angol-magyar párosítás az igazán problémás, hanem például az orosz, szlovák, román, stb. nyelvek speciális karaktereinek egy képernyőn történő megjelenítése.

A minden nyelvhez más-más kódlap használata valamennyire megoldja a problémát, de nagyon macerás lehet. Erre kínál megoldást az Unicode. Egy karakterkészlet, amely tartalmazza az összes nyelv betűit. Az UTF-8 a Unicode egy leképzése, erről bővebben Koblinger Egmont Unicode, UTF-8 című írását ajánlom. Itt arról lesz szó, hogy hogyan kell mindezeket Debian GNU/Linux szerven futó dinamikus weblapok esetén használni, beállítani.

Az itt leírtak a közeledő Sarge kiadás alapértelmezett telepítésére vonatkoznak. MySQL-ből legalább 4.1-es verzió szükséges. A 4.1-es legnagyobb újdonsága az UTF-8 mellett a subselectek támogatása, úgyhogy már csak ezért is érdemes felrakni. Csomagokra lebontva ez a következőket jelenti: mysql-common-4.1, mysql-client-4.1, mysql-server-4.1.

Az alapértelmezett beállításokon csak annyit kell változtatni, hogy a /etc/mysql/my.cnf minden szekciójába ([server], [client], stb) be kell írni a következő sort:

default-character-set=utf8

Ezt megtehetjük egy felhasználóra vonatkozóan is a ~/.my.cnf fájlban, de ettől a PHP-MySQL kommunikáció még nem biztos, hogy UTF-8 karakterkódolást fog használni, ami miatt a MySQL átkonvertálhatja az adatbázisban használt karaktereket a kliens (ami most a PHP) formátumára. Ez gondot jelent, ha a PHP ettől függetlenül UTF-8-ban várja az adatokat (és változatlanul küldi ki a böngészőnek), de a helytelen beállítások következtében azt a MySQL például ISO8859-1-é konvertálja.

Ezen a

SET CHARACTER SET utf8;
SET NAMES utf8;

utasítások kiadásával állíthatunk a PHP kódon belül, amit a mysql_select_db() hívása után érdemes megtenni.

Az adatbázisok létrehozásánál a CREATE DATABASE ujdb DEFAULT CHARACTER SET utf8; parancsot kell használni. Az összehasonlításokhoz, sorbarendezésekhez lehetséges megadni a betűk sorrendjét tartalmazó listát is (collate, egybevetés), például:

CREATE DATABASE ujdb DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

Az alapértelmezett karakterkészlet és egybevetés megadható táblánként is, vagy akár külön-külön átállítható minden attribútumra.

Az apache két helyen küldheti ki a böngészőnek a használt karakterkészletet. Egyrészt lehetőség van a HTML állományban megadni meta taggel a megjelenítéshez használni kívánt karakterkódolást, másrészt a http kapcsolat fejlécei között is szerepelhet ilyen üzenet. Utóbbi így néz ki:

$ lynx -mime_header http://palacsint.hu/ | grep charset
Content-Type: text/html; charset=utf-8

Ezt az apache konfigjában (/etc/apache/httpd.conf - 1.3.x-es apache esetén) vagy a .htaccess fájlokban az AddDefatulCharset-tel lehet átállítani, illetve kikapcsolni a következőképp:

AddDefaultCharset UTF-8
AddDefaultCharset Off

Off esetén a Content-Type fejléc nem kerül kiküldése. A html fájlokban a <head> és </head> tagek közé a következő taget kell beszúrni:

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

A két beállításnak érdemes azonosnak lennie, mert különben a böngészőtől függ, hogy melyiket fogadja el, és az nem biztos, hogy a kívánt hatást fogja eredményezni. Az apache alapbeállításai php-n belül a header() függvénnyel felülbírálhatóak.

UTF-8 fájlok szerkesztésére tökéletes a jEdit, csak arra kell figyelni, hogy a szerkesztendő fájl ténylegesen is UTF-8 karakterkódolású legyen, s ne UTF-8Y. Utóbbi a fájl elejére tesz három (itt) felesleges karaktert. Ez a néhány karakter (BOM, Byte Order Mark) lehetetlenné teszi a header() és a session_start() függvények működését. Ilyesmi hibaüzenetekre számíthatunk UTF-8Y esetén:

Warning: Cannot modify header information - headers already sent by (output started at /var/www/index.php:1) in /var/www/index.php on line 2.
Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at /var/www/index.php:1) in /var/www/index.php on line 2
Tartalom átvétel