PHP jak známo chápe řetězec jako posloupnost bajtů a nezohledňuje použité kódování. U dnes nejběžnějšího kódování UTF-8 jsou tedy funkce jako substr nebo strlen k ničemu. Alternativy pracující se znaky v různých kódováních jsou k dispozici v extenzích Iconv a MBstring. Pokud jsou tyto extenze k dispozici, tak je samozřejmě vhodné je použít. Co ale když k dispozici nejsou?
Kódování UTF-8 podporuje také funkce utf8_decode, která sice nedokáže pracovat se všemi znaky, pro samotné zjištění délky řetězce ale stačí. Pro získání podřetězce se dá využít toho, že s kódováním UTF-8 dokáže pracovat i extenze PCRE:
<?php /** Vrátí podřetězec v kódování UTF-8 * @param string * @param int * @param int * @return string * @copyright Jakub Vrána, https://php.vrana.cz/ */ function utf8_substr($string, $start, $length = null) { $chars = preg_split('~~u', $string, -1, PREG_SPLIT_NO_EMPTY); return implode(array_slice($chars, $start, $length)); } ?>
Dalo by se využít i konstrukce ~^.{10}(.{20})~su
, to by ale chtělo trochu víc počítání (ale nakonec by to nejspíš bylo rychlejší a míň paměťově náročné). Pro složitější operace bychom si mohli napsat vlastní parser – kódování UTF-8 je sice poměrně jednoduché, ale ve většině případů to je zbytečná práce.
Při provádění řetězcových operací se dá také využít znalosti cílového prostředí. Pokud např. kontrolujeme délku řetězce nebo ho zkracujeme proto, abychom ho poslali do MySQL, tak si můžeme ušetřit práci – MySQL ve striktním režimu odmítne vložit příliš dlouhá data (takže za nás provede validaci), mimo striktní režim je ořízne (takže za nás provede sanitizaci). U formulářů ukládaných do MySQL se dá tedy použít kombinace maxlength
(dobrovolná validace) a poslání do databáze (povinná sanitizace) – validaci i sanitizaci na úrovni PHP lze zcela vynechat.
Diskuse je zrušena z důvodu spamu.