Hogyan használjunk natív UTF-8 kódolást Drupal alatt
A probléma nem is olyan egyszerű, mint amilyennek látszik. Ugyanis a Drupal alapból UTF-8 kódolást használ, de ennek tényleges működését jól elrejti számunkra. Viszont egy pár módosítással a rendszer magjában elérhetjük hogy adatbázis szinten is UTF-8at használjon. Remélhetőleg ez a kiegészítésem és módosításom hamarosan hivatalosan is beépítésre kerül valamelyik következő Drupal kiadásban. Addig is itt egy megoldás, amivel mindezt végre lehet hajtani.
A rendszer jól elrejti számunkra, hogy hogyan is kezeli belsőleg a szövegeket. Ez főként a régebbi MySQL-el (4.1-nél régebbi verziókról van szó) való kompatibilitás érdekében van, amely még belsőleg nem ismerte az UTF-8 kódolást. Ennek okán a Drupal mindezt elrejtve közel binárisan tárolja az UTF-8 szövegeket (ISO-8859-1 vagy másnéven latin-1 kódolást az UTF-8 karakterek 2 bájton való tárolásával megfejelve), ezzel elkerülve a MySQL ezen hiányosságát.
Mi is itt a lényeg: pár módosítással elérhetjük hogy maga az adatbázis kapcsolódás is már UTF-8 kódolással történjen. A Drupal ezt észre sem veszi, és tovább végzi a dolgát boldogan. Ehhez a következő módosításokat eszközöltem:
- felvettem egy új sort a sites/szájt_neve/settings.php fájlban.
- módosítottam az includes/database.mysql.inc fájl db_connect függvényét a következőre:
$db_after_connect_sql = "SET NAMES 'utf-8';SET CHARACTER SET utf8";
Ez a sor definiál parancsokat, amiket majd végre kell hajtani az adatbázis kapcsolódás során. Konkrétabban beállítja hogy minden kódolás UTF-8 alapokon fog játszódni az aadtbázis műveletek során.
Most pedig következzen a módosított db_connect függvény:
<?php
function db_connect($url) {
global $db_after_connect_sql;
$url = parse_url($url);
// Allow for non-standard MySQL port.
if (isset($url['port'])) {
$url['host'] = $url['host'] .':'. $url['port'];
}
$connection = mysql_connect($url['host'], $url['user'], $url['pass'], TRUE) or die(mysql_error());
mysql_select_db(substr($url['path'], 1)) or die('unable to select database');
if (!empty($db_after_connect_sql) && $commands = explode(';', $db_after_connect_sql)) {
foreach($commands as $val) {
mysql_query($val, $connection);
}
}
return $connection;
}
?>
A függvény megpróbálja elérni a $db_after_connect_sql
változót. Kapcsolódik az adatbázishoz, majd ha nem üres a változónk, akkor megpróbál egy tömböt benerálni belőle a ;-k mentén eldarabolva a MySQLnek szóló parancsokat, majd egymás után végrehajtja őket.
Alapjaiban ennyiből áll az egész. Mostmár natív UTF-8ként használhatjuk az adatbázisunkat. Azaz minden eltárolt adat, ha az adatbázisunk is alapvetően UTF-8 kódolású - ami az egésznek ugye alapfeltétele -, szintén UTF-8 kódolásban tárolódik.
Persze itt előjöhetnek különböző problémák. Például ha alapvetően nem UTF-8 kódolású volt az adatbázisunk, vagy már meglévő adatbázisunkat akarjuk átalakítani, akkor bizony dolgoznunk kell még egy kicsit. Legegyszerűbb módszer, ha tehetjük, akkor ideiglenesen pár órára leállítjuk a drupal-ol oldalunkat a következő pár művelet erejéig, ugyanis az adatbázisunkat át kell alakítani (csak 4.1-nél újabb MySQL esetén lehetségesek a következők).
A műveletek a következők
- Leállítjuk a Drupal alapú weboldalunkat
- Kiexportáljuk az adatbázisunkat (mysql_dump)
- Csináljunk ebből a fájlból egy biztonsági másolatot, hátha vmit elrontunk.
- Végigmegyünk az adatbázison, és minden egyes UTF-8-as karaktert (azaz mindent ami nem ASCII), lecserélünk az UTF-8as megfelelőjére. Ezek általában két (esetleg három) bájton tárolt karakterek, és vmi krixkraxnak néznek ki. Mindezt persze UTF-8as környezetben tesszük.
- Az előbbire használhatunk valami megfelelő szövegszerkesztőt, ami kezel UTF-8-at, vagy írjunk rá vmi scriptet, ami megteszi ugyanezt helyettünk.
- Az adatbázisunk karakterkódolástát UTF-8ra állítjuk
- Törüljuk az összes táblát (ezért fontos a biztonsági másolat)
- Töltsük föl az új adatbázisunkat.
Sajnos pár modul még nincs igazi barátságban az UTF-8 karakter kódolással, ilyen pl. a search.module. Ezt pár helyen módosítani kellett, ugyanis az általa használt strtolower függvény nem kezeli az UTF-8 karaktereket, ezért ezeket az ezt ismerő mb_string PHP modul mb_strtolower függvényével érdemes helyettesíteni.
comments powered by Disqus