Ugrás a tartalomra

Hogyan használjunk natív UTF-8 kódolást Drupal alatt

Címkék:

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.

CsatolmányMéret
search.module30.81 kB
database.mysql.inc6.33 kB

Cache rendszer hiba

Sajnos a drupal cache-elési mechanimusával nem működik együtt a modul, úgyhogy egyenlőre csak kísérleti oldalaknál érdemes a bevezetése. Amint találok erre egy használható megoldást, egy hozzászólás keretében mindenkit tájékoztatok erről.
--
Poetro

unicode.inc

van egy unicode.inc a HEAD-ben. Az nem segít? Nem láttam egyébként ezt a patchet az issue queueban...