
🔢 Перевод чисел с PHP и JavaScript: арабские цифры в деванагари и обратно
Пользователь заполняет форму на сайте, и цифры превращаются в нечитаемые символы. Знакомая ситуация для тех, кто работает с мультиязычными проектами: непальская версия интернет-магазина показывает цены в अक्षर, а форма обратной связи не проходит валидацию из-за «неправильных» цифр.
Проблема в том, что разные языки используют разные системы числовых символов. Английский и русский, арабские цифры (0-9). Хинди, непальский, маратхи, символы деванагари (०-९). PHP и JavaScript «из коробки» не переключаются между ними. При этом задача решается без единой внешней библиотеки, хватает встроенных функций работы со строками. Никаких подключаемых зависимостей, никаких сторонних API.
Ниже, два готовых фрагмента кода, которые закрывают вопрос за 5 минут. Без фреймворков, без Composer-пакетов, без npm-зависимостей, на чистом PHP и ванильном JavaScript. Скопировали, подставили свои символы, заработало.
💡 Быстрый обзор:
- Скопируйте PHP-функцию в functions.php темы или через плагин Code Snippets, она переводит арабские цифры в деванагари и обратно
- Для фронтенда используйте готовый JavaScript-код с объектами-словарями, конвертация на лету прямо в поле ввода
- Замена идёт по таблице соответствия глифов, а не математически, метод универсален для любой письменности
- Протестируйте: передайте 1234 и получите १२३४, и наоборот, обе стороны работают симметрично
Как устроены числовые системы в разных языках
Большинство сайтов работает с арабскими цифрами: 0 1 2 3 4 5 6 7 8 9. Исторически эта система пришла из Индии, но закрепилась через арабский мир, отсюда и название.
Альтернативные наборы существуют в десятках письменностей. Деванагари (хинди, непальский, маратхи) использует собственный ряд: ० १ २ ३ ४ ५ ६ ७ ८ ९. Восточно-арабские цифры (арабский, персидский, урду), другой набор: ٠ ١ ٢ ٣ ٤ ٥ ٦ ٧ ٨ ٩. Бенгальский, тайский, кхмерский: у каждого свои глифы и свои диапазоны в таблице Unicode. Всего таких систем больше двадцати.
Но числовое значение остаётся тем же. 5, ५ и ٥, это одно и то же число «пять», просто записанное разными символами. Поэтому перевод между системами, это замена глифов по таблице соответствия, а не математическая конвертация. Ничего пересчитывать не нужно, достаточно знать правильные пары символов.
Именно этот принцип и заложен в коде ниже.
Шаг 1: Перевод чисел с помощью PHP

PHP-подход максимально простой: функция str_replace() принимает два массива, что искать и на что заменять. Строка проходит один проход, и все совпадения заменяются.
Добавьте этот код в functions.php дочерней темы или через плагин Code Snippets. Функция принимает число или строку с цифрами и возвращает результат с символами деванагари.
1 <?php 2 /** 3 * Конвертирует арабские цифры в символы деванагари (хинди, непальский). 4 * 5 * @param string|int $input Строка или число для конвертации. 6 * @return string Строка с цифрами деванагари. 7 */ 8 function convert_to_devanagari($input) { 9 $english = array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9"); 10 $devanagari = array("०", "१", "२", "३", "४", "५", "६", "७", "८", "९"); 11 12 return str_replace($english, $devanagari, (string) $input); 13 } 14 15 /* Пример использования */ 16 echo convert_to_devanagari(2026); 17 // Вывод: २०२६ 18 ?>
Что здесь происходит: str_replace() идёт по массиву $english и для каждого элемента (например, "2") подставляет соответствующий элемент из $devanagari ("२"). Приведение к (string) гарантирует, что функция отработает и с числом, и со строкой.
Обратная конвертация, из деванагари в арабские цифры, делается перестановкой массивов местами:
1 <?php 2 /** 3 * Конвертирует символы деванагари обратно в арабские цифры. 4 * 5 * @param string $input Строка с цифрами деванагари. 6 * @return string Строка с арабскими цифрами. 7 */ 8 function convert_from_devanagari($input) { 9 $english = array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9"); 10 $devanagari = array("०", "१", "२", "३", "४", "५", "६", "७", "८", "९"); 11 12 return str_replace($devanagari, $english, $input); 13 } 14 15 /* Пример */ 16 echo convert_from_devanagari('२०२६'); 17 // Вывод: 2026 18 ?>
Массивы те же, меняется только порядок аргументов. Первый массив теперь содержит символы деванагари (то, что ищем), второй, арабские цифры (на что заменяем).
Где применить. Функция пригодится в любом месте темы, где выводятся числа: цены товаров в WooCommerce, даты в блоге, нумерация страниц. Оборачивайте вызов там, где нужна локализация цифр под конкретную аудиторию.
Обработка граничных случаев в PHP
Функция convert_to_devanagari() принимает string|int, но на практике вход может быть любым. Что будет, если передать null, пустую строку или строку без цифр? (string) null даст пустую строку, str_replace() с пустой строкой тоже вернет пустую, ошибки не будет. Строка без цифр (например, "Привет") вернется без изменений, замена просто не найдет совпадений.
Если число содержит разделители (запятые для тысяч, точку для дробной части), они останутся на месте, заменятся только сами цифры. Для чисел с плавающей точкой это поведение корректно, но если формат чисел важен и разделители должны меняться под локаль, добавьте отдельную обработку через number_format() до конвертации.
Для очень длинных чисел (например, 20-значные идентификаторы) подход работает без изменений: str_replace() обрабатывает строку любой длины, ограничение только в доступной памяти PHP. Символы деванагари занимают по 3 байта в UTF-8, поэтому итоговая строка будет длиннее исходной в байтах. Для подсчета символов используйте mb_strlen(), а не strlen().
Шаг 2: Перевод чисел с помощью JavaScript
На фронтенде та же логика реализуется через объекты-словари и метод String.replace() с регулярным выражением. Это удобно для динамических интерфейсов: пользователь вводит число в поле, а скрипт на лету показывает эквивалент в деванагари.
Разместите этот код в отдельном .js-файле темы или через wp_add_inline_script в functions.php. Никаких зависимостей, чистый ES5, работает даже в старых браузерах.
1 /** 2 * Словари для перевода между арабскими цифрами и деванагари. 3 */ 4 var englishToDevanagari = { 5 '0': '०', '1': '१', '2': '२', '3': '३', '4': '४', 6 '5': '५', '6': '६', '7': '७', '8': '८', '9': '९' 7 }; 8 9 var devanagariToEnglish = { 10 '०': '0', '१': '1', '२': '2', '३': '3', '४': '4', 11 '५': '5', '६': '6', '७': '7', '८': '8', '९': '9' 12 }; 13 14 /** 15 * Конвертирует арабские цифры в строке в символы деванагари. 16 * @param {string|number} input 17 * @returns {string} 18 */ 19 function toDevanagari(input) { 20 return String(input).replace(/[0-9]/g, function(match) { 21 return englishToDevanagari[match]; 22 }); 23 } 24 25 /** 26 * Конвертирует символы деванагари в арабские цифры. 27 * @param {string} input 28 * @returns {string} 29 */ 30 function fromDevanagari(input) { 31 return input.replace(/[०-९]/g, function(match) { 32 return devanagariToEnglish[match]; 33 }); 34 } 35 36 // Примеры: 37 console.log(toDevanagari(9857)); // ९८५७ 38 console.log(fromDevanagari('१२३४')); // 1234
Ключевой момент, регулярное выражение /[0-9]/g. Флаг g (global) заставляет replace() обработать каждую цифру в строке, а не только первую. Анонимная функция-колбэк получает совпавший символ и возвращает его эквивалент из словаря.
Для цифр деванагари используется диапазон [०-९], в Unicode эти символы идут подряд, поэтому регулярка работает корректно.
Где применить. Живой ввод в формах (конвертация на лету при наборе), отображение цен и дат в локализованных версиях сайта, обратная конвертация перед отправкой формы на сервер, чтобы в базу всегда попадали арабские цифры.
Практический пример: форма обратной связи с конвертацией на лету
Соберем оба подхода в работающую связку. Допустим, на непальской версии сайта есть форма заказа, где пользователь вводит сумму в деванагари. Задача: показать введенное число в обеих системах для проверки и отправить на сервер арабские цифры.
Разметка формы содержит <input> и блок предпросмотра. На каждое нажатие клавиши в поле срабатывает обработчик input, который вызывает toDevanagari() и выводит результат в соседний <span>. При отправке формы срабатывает fromDevanagari(), и в теле POST-запроса на сервер уходят уже арабские цифры. Серверная часть на PHP получает число в стандартном формате и работает с ним как обычно, без дополнительной конвертации.
Этот же шаблон применим к полям цен, дат, номеров телефонов и любым другим полям, где пользователь ожидает увидеть родную систему цифр, а система должна хранить унифицированный формат. Конвертация занимает микросекунды и не влияет на отзывчивость интерфейса.
Смотрите также: видео по числовым системам в программировании
Для более широкого взгляда на тему, как устроены системы счисления в коде и как конвертировать между ними на JavaScript, посмотрите этот разбор от Techno Geek. Охватывает двоичную, восьмеричную и десятичную системы с готовым проектом.
⁉️🤔 Частые вопросы
Можно ли этим же методом перевести цифры на арабский (восточно-арабские символы)?
Да. Замените массив деванагари на восточно-арабские символы:
array("٠", "١", "٢", "٣", "٤", "٥", "٦", "٧", "٨", "٩"). Логика та же,str_replace()в PHP и словарь с регуляркой в JS. Точно так же адаптируется под бенгальский, тайский, кхмерский и любую другую письменность с собственными цифровыми глифами.
Безопасно ли использовать str_replace() для многобайтовых строк в PHP?
Да,
str_replace()корректно работает с UTF-8 и многобайтовыми символами, в отличие отstrpos()илиsubstr(), которым нужны mbstring-аналоги. Символы деванагари (२,३) занимают по 3 байта в UTF-8, ноstr_replace()обрабатывает их побайтово-безопасно, потому что ищет точное бинарное совпадение последовательности. Проблем не будет.
Что делать, если в строке смешаны арабские цифры и символы деванагари?
Обе функции обрабатывают только свои диапазоны. Если на вход
convert_to_devanagari()пришла строка"Цена: 500 रुपей", цифра500станет५००, а текст останется нетронутым. Обратная функцияconvert_from_devanagari()тронет только деванагари-цифры. Смешанный ввод обрабатывается корректно автоматически.
Как применить конвертацию ко всем числам на странице WordPress без правки каждого шаблона?
Используйте JavaScript-подход из шага 2 и запустите обход DOM-узлов при загрузке страницы. Найдите все текстовые узлы с цифрами (через
TreeWalkerили рекурсивный обходchildNodes), применитеtoDevanagari()к содержимому. Для PHP-подхода на серверной стороне, фильтр наthe_contentилиgettext, если числа встроены в переводы.
Где взять таблицы символов для других письменностей?
Авторитетный источник, Unicode Consortium. Для цифр деванагари это диапазон U+0966-U+096F. Восточно-арабские, U+0660-U+0669. Бенгальские, U+09E6-U+09EF. Достаточно скопировать символы из таблицы и подставить в массивы, код менять не придётся.
Производительность и ограничения подхода
str_replace() с массивами из 10 элементов делает ровно 10 сравнений для каждой позиции в строке. Для типичной строки с 5-10 цифрами это 50-100 операций, время выполнения измеряется микросекундами. Для сравнения, подход через preg_replace_callback() с регулярным выражением добавляет накладные расходы на компиляцию шаблона и вызов колбэка для каждого совпадения. Разница на малых строках незаметна, но str_replace() выигрывает на больших объемах.
Основное ограничение подхода в том, что он заменяет глифы, а не семантику числа. Если потребуется арифметика над числами в деванагари (сложение, умножение), символы деванагари не будут восприняты PHP как числа. Всегда конвертируйте в арабские цифры перед математическими операциями и обратно после. Это не недостаток метода, а следствие разницы между письменностью и числовым типом данных.
Еще один нюанс: метод предполагает однозначное соответствие «один глиф, одна цифра». Для письменностей, где числа записываются составными лигатурами (как в некоторых исторических системах), подход с простой заменой не сработает. Но для всех современных индийских письменностей (деванагари, бенгальский, гурмукхи, гуджарати, ория, тамильский, телугу, каннада, малаялам), а также для восточно-арабских цифр, соответствие строго 1 к 1, и метод работает безотказно.
Что ставить в production: PHP, JavaScript или оба варианта?
PHP-решение, для случаев, когда числа должны быть отрендерены в нужной системе символов на сервере до отправки HTML. Это правильно для SEO: поисковик видит контент сразу в целевой локали, а не арабские цифры, которые потом подменяются скриптом. Для интернет-магазина на WooCommerce это означает, что цены в каталоге и карточке товара индексируются с цифрами деванагари, что положительно влияет на ранжирование в непальском и хинди-сегментах.
JavaScript-вариант, для динамического взаимодействия: поле ввода с мгновенным предпросмотром, переключение языка интерфейса без перезагрузки, конвертация данных формы перед отправкой. Он также незаменим для одностраничных приложений (SPA), где сервер отдает JSON с арабскими цифрами, а фронтенд рендерит их в локали пользователя.
На практике хорошо работает связка: PHP рендерит страницу с локализованными цифрами для индексации, а JavaScript подхватывает пользовательский ввод и конвертирует туда-обратно на лету. Оба фрагмента кода, без внешних зависимостей, меньше 40 строк на двоих, и закрывают задачу полностью для любой письменности с собственными цифровыми глифами.
Перед выкладкой в production проверьте три сценария: прямой вызов функции с числом, строку со смешанным содержимым (цифры плюс текст) и обратную конвертацию. Убедитесь, что на сервер всегда попадают арабские цифры, а в интерфейсе пользователь видит ту систему, которая соответствует его языковым ожиданиям. Пять минут на тестирование экономят часы отладки на живом трафике.
Скопируйте оба фрагмента кода в проект, подставьте нужные символы из таблицы Unicode под свою письменность, и задача закрыта. Всё, что нужно, уже встроено в язык.



