Назад

Пишем свою функцию транслитерации на PHP

Главная
Блог
Пишем свою функцию транслитерации на PHP

Транслитерация — это преобразование текста из одной системы письма в другую, где каждый символ одного языка заменяется соответствующим символом или сочетанием символов другого языка. В веб-разработке транслитерация часто используется для:

  • Создания ЧПУ (человеко-понятных URL)

  • Обработки поисковых запросов

  • Генерации логинов и имен файлов

  • Международной поддержки приложений

Базовая функция транслитерации

Начнем с создания простой, но функциональной реализации:

/**
 * Функция транслитерации строки
 * 
 * @param string $str Исходная строка для преобразования
 * @param bool $reverse Флаг обратного преобразования (EN->RU)
 * @return string Результат транслитерации
 */
function transliterate($str, $reverse = false) 
{
    $translitMap = [
        // Прописные буквы
        'А' => 'A', 'Б' => 'B', 'В' => 'V', 'Г' => 'G',
        'Д' => 'D', 'Е' => 'E', 'Ё' => 'Yo', 'Ж' => 'Zh',
        'З' => 'Z', 'И' => 'I', 'Й' => 'Y', 'К' => 'K',
        'Л' => 'L', 'М' => 'M', 'Н' => 'N', 'О' => 'O',
        'П' => 'P', 'Р' => 'R', 'С' => 'S', 'Т' => 'T',
        'У' => 'U', 'Ф' => 'F', 'Х' => 'Kh', 'Ц' => 'Ts',
        'Ч' => 'Ch', 'Ш' => 'Sh', 'Щ' => 'Shch', 'Ъ' => '',
        'Ы' => 'Y', 'Ь' => '', 'Э' => 'E', 'Ю' => 'Yu',
        'Я' => 'Ya',
        
        // Строчные буквы
        'а' => 'a', 'б' => 'b', 'в' => 'v', 'г' => 'g',
        'д' => 'd', 'е' => 'e', 'ё' => 'yo', 'ж' => 'zh',
        'з' => 'z', 'и' => 'i', 'й' => 'y', 'к' => 'k',
        'л' => 'l', 'м' => 'm', 'н' => 'n', 'о' => 'o',
        'п' => 'p', 'р' => 'r', 'с' => 's', 'т' => 't',
        'у' => 'u', 'ф' => 'f', 'х' => 'kh', 'ц' => 'ts',
        'ч' => 'ch', 'ш' => 'sh', 'щ' => 'shch', 'ъ' => '',
        'ы' => 'y', 'ь' => '', 'э' => 'e', 'ю' => 'yu',
        'я' => 'ya'
    ];
    
    if ($reverse) {
        // Для обратной транслитерации нужна особая обработка
        $translitMap = [
            'Zh' => 'Ж', 'Kh' => 'Х', 'Ts' => 'Ц', 'Ch' => 'Ч',
            'Sh' => 'Ш', 'Shch' => 'Щ', 'Yu' => 'Ю', 'Ya' => 'Я',
            'Yo' => 'Ё', 'zh' => 'ж', 'kh' => 'х', 'ts' => 'ц',
            'ch' => 'ч', 'sh' => 'ш', 'shch' => 'щ', 'yu' => 'ю',
            'ya' => 'я', 'yo' => 'ё',
            // Односимвольные замены
            'A' => 'А', 'B' => 'Б', 'V' => 'В', 'G' => 'Г',
            'D' => 'Д', 'E' => 'Е', 'Z' => 'З', 'I' => 'И',
            'Y' => 'Й', 'K' => 'К', 'L' => 'Л', 'M' => 'М',
            'N' => 'Н', 'O' => 'О', 'P' => 'П', 'R' => 'Р',
            'S' => 'С', 'T' => 'Т', 'U' => 'У', 'F' => 'Ф',
            'a' => 'а', 'b' => 'б', 'v' => 'в', 'g' => 'г',
            'd' => 'д', 'e' => 'е', 'z' => 'з', 'i' => 'и',
            'y' => 'й', 'k' => 'к', 'l' => 'л', 'm' => 'м',
            'n' => 'н', 'o' => 'о', 'p' => 'п', 'r' => 'р',
            's' => 'с', 't' => 'т', 'u' => 'у', 'f' => 'ф'
        ];
        
        // Сортируем по длине ключа в обратном порядке для правильной замены
        uksort($translitMap, function($a, $b) {
            return strlen($b) - strlen($a);
        });
    }
    
    return strtr($str, $translitMap);
}

Улучшенная версия с дополнительными возможностями

Добавим поддержку разных стандартов транслитерации и обработку специальных символов:

/**
 * Улучшенная функция транслитерации
 * 
 * @param string $str Исходная строка
 * @param bool $reverse Направление преобразования
 * @param string $standard Используемый стандарт (iso, gost, php)
 * @return string
 */
function advancedTransliterate($str, $reverse = false, $standard = 'iso') 
{
    // Определяем таблицу транслитерации по выбранному стандарту
    $standards = [
        'iso' => [
            // ISO 9-1995 стандарт
            'А'=>'A', 'Б'=>'B', 'В'=>'V', 'Г'=>'G',
            'Д'=>'D', 'Е'=>'E', 'Ё'=>'Yo', 'Ж'=>'Zh',
            'З'=>'Z', 'И'=>'I', 'Й'=>'J', 'К'=>'K',
            'Л'=>'L', 'М'=>'M', 'Н'=>'N', 'О'=>'O',
            'П'=>'P', 'Р'=>'R', 'С'=>'S', 'Т'=>'T',
            'У'=>'U', 'Ф'=>'F', 'Х'=>'X', 'Ц'=>'C',
            'Ч'=>'Ch', 'Ш'=>'Sh', 'Щ'=>'Shh', 'Ъ'=>'',
            'Ы'=>'Y', 'Ь'=>'', 'Э'=>'E', 'Ю'=>'Yu',
            'Я'=>'Ya'
        ],
        'gost' => [
            // ГОСТ 7.79-2000 система Б
            'А'=>'A', 'Б'=>'B', 'В'=>'V', 'Г'=>'G',
            'Д'=>'D', 'Е'=>'E', 'Ё'=>'Yo', 'Ж'=>'Zh',
            'З'=>'Z', 'И'=>'I', 'Й'=>'J', 'К'=>'K',
            'Л'=>'L', 'М'=>'M', 'Н'=>'N', 'О'=>'O',
            'П'=>'P', 'Р'=>'R', 'С'=>'S', 'Т'=>'T',
            'У'=>'U', 'Ф'=>'F', 'Х'=>'Kh', 'Ц'=>'Ts',
            'Ч'=>'Ch', 'Ш'=>'Sh', 'Щ'=>'Shch', 'Ъ'=>'',
            'Ы'=>'Y', 'Ь'=>'', 'Э'=>'E', 'Ю'=>'Yu',
            'Я'=>'Ya'
        ]
    ];
    
    // Добавляем строчные варианты
    foreach ($standards as &$map) {
        $lowerMap = [];
        foreach ($map as $cyr => $lat) {
            $lowerMap[mb_strtolower($cyr, 'UTF-8')] = mb_strtolower($lat, 'UTF-8');
        }
        $map = array_merge($map, $lowerMap);
    }
    
    $translitMap = $standards[$standard] ?? $standards['iso'];
    
    if ($reverse) {
        // Создаем карту для обратного преобразования
        $reverseMap = [];
        foreach ($translitMap as $cyr => $lat) {
            if (!empty($lat) && !isset($reverseMap[$lat])) {
                $reverseMap[$lat] = $cyr;
            }
        }
        
        // Сортируем по длине ключа в обратном порядке
        uksort($reverseMap, function($a, $b) {
            return strlen($b) - strlen($a);
        });
        
        $translitMap = $reverseMap;
    }
    
    // Обработка строки
    $result = strtr($str, $translitMap);
    
    // Дополнительная обработка для ЧПУ
    if (!$reverse) {
        $result = preg_replace('/[^\w\-]/u', '-', $result);
        $result = preg_replace('/\-+/', '-', $result);
        $result = trim($result, '-');
    }
    
    return $result;
}

Практическое применение

1. Генерация ЧПУ (SEO-friendly URL)

function generateSlug($title) {
    $slug = advancedTransliterate($title);
    $slug = mb_strtolower($slug, 'UTF-8');
    return $slug;
}

echo generateSlug('Пример статьи о транслитерации');
// primer-stati-o-transliteracii

2. Обработка поисковых запросов

$searchQuery = 'transliteraciya';
$russianQuery = advancedTransliterate($searchQuery, true);

$db->query("SELECT * FROM articles 
           WHERE title LIKE '%{$searchQuery}%' 
           OR title LIKE '%{$russianQuery}%'");

3. Создание имен файлов

$filename = advancedTransliterate('Документ 123.docx');
// dokument-123.docx

Альтернативные методы транслитерации

1. Использование расширения intl

if (extension_loaded('intl')) {
    $transliterator = Transliterator::create('Russian-Latin/BGN');
    $result = $transliterator->transliterate('Текст для транслитерации');
}

2. Использование iconv

$result = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', 'Русский текст');

Заключение

Мы рассмотрели различные способы реализации транслитерации на PHP. Базовая функция подойдет для простых случаев, тогда как улучшенная версия с поддержкой разных стандартов будет полезна в более сложных проектах. Для enterprise-решений рекомендуется использовать расширение intl или специализированные библиотеки.

Ключевые моменты для запоминания:

  • Всегда определяйте требования к транслитерации перед реализацией

  • Учитывайте необходимость обратного преобразования

  • Выбирайте подходящий стандарт транслитерации

  • Обрабатывайте крайние случаи и специальные символы

  • Для критически важных задач используйте проверенные библиотеки

Примеры кода из этой статьи можно адаптировать под свои нужды, расширяя таблицы транслитерации и добавляя новую функциональность.

Нужен надежный исполнитель?
Разрабатываем сайты, выполняем миграцию на Битрикс, дорабатываем функционал, сопровождаем проекты, а также занимаемся поисковым продвижением и комплексным маркетингом
Получить консультацию
Читайте по теме
Все статьи
Нужен надежный исполнитель?
Разрабатываем сайты, выполняем миграцию на Битрикс, дорабатываем функционал, сопровождаем проекты, а также занимаемся поисковым продвижением и комплексным маркетингом
Получить консультацию
Все статьи