latin (fallback si intl n’est pas dispo) function translit_ru_to_lat(string $s): string { if (class_exists('Transliterator')) { // "Russian-Latin/BGN" produit Parizh (Париж) -> "parizh" $t = \Transliterator::create('Russian-Latin/BGN; Lower();'); if ($t) return $t->transliterate($s); } $map = [ 'а'=>'a','б'=>'b','в'=>'v','г'=>'g','д'=>'d','е'=>'e','ё'=>'e','ж'=>'zh','з'=>'z','и'=>'i','й'=>'i','к'=>'k', 'л'=>'l','м'=>'m','н'=>'n','о'=>'o','п'=>'p','р'=>'r','с'=>'s','т'=>'t','у'=>'u','ф'=>'f','х'=>'kh','ц'=>'ts', 'ч'=>'ch','ш'=>'sh','щ'=>'shch','ъ'=>'','ы'=>'y','ь'=>'','э'=>'e','ю'=>'yu','я'=>'ya', ]; $s = mb_strtolower($s, 'UTF-8'); return strtr($s, $map); } // Retourne une liste de candidats latins (pour LIKE) à partir d’une saisie q function city_query_candidates(string $q): array { $q = trim($q); if ($q === '') return []; $cands = []; $cands[] = mb_strtolower($q, 'UTF-8'); // saisie brute (si déjà latine) // charger alias RU -> latin $aliases = @include __DIR__ . '/city_aliases_ru.php'; if (!is_array($aliases)) $aliases = []; if (has_cyrillic($q)) { // 1) correspondance par préfixe dans les alias (ПАР → Paris) $key = norm_key($q); foreach ($aliases as $ru => $lat) { if (strpos(norm_key($ru), $key) === 0) { $cands[] = $lat; } } // 2) translittération simple (Париж -> parizh) $cands[] = translit_ru_to_lat($q); } // Normalisation légère des candidats (minuscules, accents retirés si possible) $res = []; foreach (array_unique($cands) as $c) { $lc = mb_strtolower($c, 'UTF-8'); // enlever accents (si intl transliterator dispo) if (class_exists('Transliterator')) { $t = \Transliterator::create('Any-Latin; Latin-ASCII;'); if ($t) $lc = $t->transliterate($lc); } $res[] = $lc; } return array_values(array_unique($res)); }