PHP nabízí vskutku rozsáhlé možnosti pro práci s poli a to včetně třídění. Problém ovšem nastává, pokud je potřeba setřídit prvky pole, jejichž počáteční písmena neobsahují pouze znaky anglické abecedy, ale také další písmena s diakritikou, či jiné symboly. V takovém případě jsou tyto položky umístěny na začátek, či konec pole (záleží na nastavení serveru), kam přitom nemusí vůbec patřit. Tento problém je sice možné obejít setříděním prvků při výběru z databáze, někdy ale stejně může nastat situace, kdy je nutné seřadit až samotné pole.

Sám jsem na tuto situaci narazil, a proto jsem se rozhodl, že se pokusím napsat vlastní třídící funkci, která bude prvky polí řadit korektně.

Je využito funkce usort(), která umožňuje pro třídění definovat vlastní funkci, ve které dochází k porovnávání jednotlivých prvků mezi sebou na základě vlastních kritérií. K tomu, aby byly jednotlivé položky pole správně řazeny, bylo nutné před samotným porovnáváním jednotlivých dvojic, převést speciální znaky na znaky anglické abecedy. Toto bohužel vyžaduje mít seznam všech speciálních znaků s překlady na znaky standardní. Tento seznam jsem však našel v jednom modulu pro CMS Drupal a mírně ho poupravil – pro korektní zařazení písmen s háčky až za ty bez háčků.

<?php
$items = array(...);
usort($items, "_sort_by_title_ascii");

function _sort_by_title_ascii($a, $b) {
  static $translations;
  if (!$translations) {
    $path = '...';
    if (is_file($path .'/translations.txt')) {
      $translations = parse_ini_file($path .'/translations.txt');
    }
  }
  $A = strtr($a, $translations);
  $B = strtr($b, $translations);
  return strnatcasecmp($A, $B);
}
?>

Zdrojový kód s příkladem včetně souboru s překlady nestandardních znaků je možné stáhnout v přiloženém archivu.

PřílohaVelikost
kecisort.zip2.04 KB

To nejde použít setlocale()?

To nejde použít setlocale()? Mě to tak teda v kombinaci s ksort() funguje.

Je možné, že to v aktuální

Je možné, že to v aktuální verzi/nastavení PHP již funguje, ale mně to rozhodně nefungovalo.

setlocale() hlavně závisí na

setlocale() hlavně závisí na systému, takže když si chci napsat univerzální knihovnu, nezbývá, než si to vyřešit po svém.

-- ripper

Diakritika hezky srovnaná,

Diakritika hezky srovnaná, akorát to řadí blbě Ch Ca Cá Cha Chl Ci Co