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

  1. Leállítjuk a Drupal alapú weboldalunkat
  2. Kiexportáljuk az adatbázisunkat (mysql_dump)
  3. Csináljunk ebből a fájlból egy biztonsági másolatot, hátha vmit elrontunk.
  4. 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.
  5. 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.
  6. Az adatbázisunk karakterkódolástát UTF-8ra állítjuk
  7. Törüljuk az összes táblát (ezért fontos a biztonsági másolat)
  8. 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