Определение языка текста в PHP: инструменты и примеры
Определение языка текста в PHP: обзор подходов
Какое решение является наиболее эффективным для определения языка текста в PHP?
Наиболее эффективным и удобным для использования в современных проектах является библиотека patrickschur/language-detection, устанавливаемая через Composer. Она не требует внешних API, работает на основе статистических моделей N-грамм и поддерживает более 100 языков. Библиотека активно поддерживается и не имеет внешних зависимостей, кроме PHP 7.2+.
composer require patrickschur/language-detectionопределить язык php (определение языка в php)
Пример использования:
<?php
require_once __DIR__ . '/vendor/autoload.php';
use LanguageDetection\Language;
$language = new Language();
$text = 'Привет, как дела?';
$result = $language->detect($text)->close();
echo 'Язык: ' . $result[0]['language'] . ' (уверенность: ' . $result[0]['confidence'] . ')';
/* Результат:
Язык: ru (уверенность: 0.999...)
*/
Пояснение шагов:
- Установка библиотеки через Composer.
- Подключение автозагрузчика и импорт класса Language.
- Создание экземпляра Language (по умолчанию загружаются все языки; можно ограничить список через конструктор).
- Метод detect() возвращает объект LanguageResult, который содержит массив языков с вероятностями.
- Вызов close() завершает обработку и возвращает массив результатов, отсортированных по убыванию вероятности.
Возможные проблемы и ошибки:
- Ошибка "Call to undefined method Language::detect()" - неверная версия библиотеки (старая 2.x). В версии 2.x используется detect() без close(). Используйте версию ^4.0.
- Низкая точность для коротких текстов (менее 20 символов). Решение: увеличить длину анализируемого текста или использовать дополнительную проверку.
- Проблемы с кодировкой: текст должен быть в UTF-8. Если исходная строка в другой кодировке, предварительно конвертировать через mb_convert_encoding().
Как определить язык с помощью библиотеки Text_LanguageDetect (PEAR)?
Старая, но до сих пор рабочая библиотека из PEAR. Подходит для проектов без Composer или с PHP 5.x. Устанавливается через pear install Text_LanguageDetect.
pear install Text_LanguageDetect
<?php
require_once 'Text/LanguageDetect.php';
$detector = new Text_LanguageDetect();
$result = $detector->detect('Hello world');
if ($result) {
list($language, $score) = each($result);
echo 'Язык: ' . $language;
} else {
echo 'Не удалось определить';
}
/* Результат:
Язык: english
*/
Проблемы: библиотека устарела (последняя версия 0.3.0 от 2016 года), не поддерживает некоторые новые языки. Ошибка "Class 'Text_LanguageDetect' not found" - требуется установка PEAR и библиотеки. В современных версиях PHP могут возникать ошибки совместимости.
Как определить язык через внешний API (Google Translate, Yandex)?
Использование облачных сервисов даёт высокую точность, но требует интернет-соединения и ключей API. Пример для Google Cloud Translation API:
composer require google/cloud-translate
<?php
require_once 'vendor/autoload.php';
use Google\Cloud\Translate\V2\TranslateClient;
$translate = new TranslateClient(['key' => 'ваш_ключ']);
$result = $translate->detectLanguage('Bonjour le monde');
echo 'Язык: ' . $result['languageCode'];
/* Результат:
Язык: fr
*/
Проблемы: необходимость регистрации в облаке, оплата (хотя есть бесплатный лимит), задержки сети, блокировка запросов при превышении лимита. Ошибка 403 - неверный ключ или не включён API.
Как определить язык с помощью простой эвристики (поиск по словарю)?
Для ограниченного набора языков можно создать свой простой определитель на основе частотных слов. Не требует внешних библиотек, но точность низкая.
<?php
$dictionaries = [
'ru' => ['привет', 'как', 'дело', 'спасибо'],
'en' => ['hello', 'how', 'thanks', 'please'],
];
$text = 'Hello, how are you?';
$words = mb_strtolower($text);
$scores = [];
foreach ($dictionaries as $lang => $list) {
$count = 0;
foreach ($list as $word) {
if (strpos($words, $word) !== false) {
$count++;
}
}
$scores[$lang] = $count;
}
arsort($scores);
echo 'Определённый язык: ' . key($scores);
/* Результат:
Определённый язык: en
*/
Проблемы: работает только для заранее заданных слов, ложные срабатывания для похожих языков (например, русский и украинский). Не подходит для коротких текстов.
Как определить язык с помощью расширения PHP (например, TextCat)?
Расширение TextCat (текстовый классификатор) доступно через PECL. Устанавливается pecl install textcat. Требует компиляции.
pecl install textcat
<?php
textcat_init('/path/to/textcat.ini');
$language = textcat_classify('Ceci est un texte français');
echo $language;
/* Результат:
french
*/
Проблемы: требуется компиляция расширения, нет встроенной поддержки на многих хостингах, редко обновляется. Ошибка "undefined function textcat_classify" - расширение не установлено.
Расширенные примеры определения языка в PHP
Пример 1: Пакетное определение языка для массива текстов
Обработка нескольких текстов с сохранением результатов в файл.
<?php
require_once 'vendor/autoload.php';
use LanguageDetection\Language;
$texts = [
'Привет, мир!',
'Hello, world!',
'Hola, mundo!',
'Bonjour tout le monde'
];
$language = new Language();
$results = [];
foreach ($texts as $text) {
$detection = $language->detect($text)->close();
$results[] = [
'text' => mb_substr($text, 0, 20) . '...',
'language' => $detection[0]['language'],
'confidence' => round($detection[0]['confidence'], 2)
];
}
file_put_contents('results.json', json_encode($results, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
echo 'Результаты сохранены в results.json';
?>
Результаты сохранены в results.json
Содержимое results.json:
[
{
"text": "Привет, мир!...",
"language": "ru",
"confidence": 1
},
{
"text": "Hello, world!...",
"language": "en",
"confidence": 1
},
{
"text": "Hola, mundo!...",
"language": "es",
"confidence": 1
},
{
"text": "Bonjour tout le ...",
"language": "fr",
"confidence": 0.99
}
]
Пример 2: Определение языка с фильтрацией по списку поддерживаемых языков
Ограничение набора языков для повышения скорости и точности.
<?php
require_once 'vendor/autoload.php';
use LanguageDetection\Language;
// Только английский, немецкий, французский, испанский
$supported = ['en', 'de', 'fr', 'es'];
$language = new Language($supported);
$text = 'Guten Morgen! Wie geht es Ihnen?';
$result = $language->detect($text)->close();
print_r($result);
?>
Array
(
[0] => Array
(
[language] => de
[confidence] => 0.876
)
[1] => Array
(
[language] => en
[confidence] => 0.124
)
)
Пример 3: Интеграция с кэшированием результатов определения
Избежание повторного анализа одного и того же текста.
<?php
require_once 'vendor/autoload.php';
use LanguageDetection\Language;
function detectLanguageWithCache($text, $cacheFile = 'lang_cache.txt') {
$hash = md5($text);
$cache = [];
if (file_exists($cacheFile)) {
$cache = json_decode(file_get_contents($cacheFile), true) ?? [];
}
if (isset($cache[$hash])) {
return $cache[$hash];
}
$language = new Language();
$detection = $language->detect($text)->close();
$result = $detection[0]['language'];
$cache[$hash] = $result;
file_put_contents($cacheFile, json_encode($cache, JSON_UNESCAPED_UNICODE));
return $result;
}
echo detectLanguageWithCache('The quick brown fox'); // en
?>
Пример 4: Обработка ошибок при использовании внешнего API (Google)
Повторные попытки и логирование.
<?php
require_once 'vendor/autoload.php';
use Google\Cloud\Translate\V2\TranslateClient;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
function detectWithRetry($text, $apiKey, $retries = 3) {
$logger = new Logger('translator');
$logger->pushHandler(new StreamHandler('lang_errors.log', Logger::WARNING));
$translate = new TranslateClient(['key' => $apiKey]);
for ($attempt = 1; $attempt <= $retries; $attempt++) {
try {
$response = $translate->detectLanguage($text);
return $response['languageCode'];
} catch (Exception $e) {
$logger->warning("Attempt $attempt failed: " . $e->getMessage());
if ($attempt === $retries) {
throw $e;
}
sleep(2);
}
}
}
echo detectWithRetry('Hello', 'your_api_key');
?>
en
Пример 5: Определение языка для файла с поддержкой кодировок
Чтение файла, конвертация в UTF-8 и определение языка.
<?php
require_once 'vendor/autoload.php';
use LanguageDetection\Language;
function detectFromFile($filePath) {
$content = file_get_contents($filePath);
if ($content === false) {
throw new RuntimeException("Cannot read file: $filePath");
}
// Определяем кодировку
$encoding = mb_detect_encoding($content, ['UTF-8', 'Windows-1251', 'ISO-8859-1'], true);
if ($encoding !== 'UTF-8') {
$content = mb_convert_encoding($content, 'UTF-8', $encoding);
}
$language = new Language();
$result = $language->detect($content)->close();
return $result[0]['language'];
}
echo detectFromFile('/path/to/text.txt');
?>
Пример 6: Сравнение производительности библиотек
Тестирование времени выполнения для 1000 коротких текстов.
<?php
require_once 'vendor/autoload.php';
$samples = array_fill(0, 1000, 'This is a sample English text for benchmarking.');
$start = microtime(true);
$language = new Language();
foreach ($samples as $text) {
$language->detect($text)->close();
}
echo 'patrickschur/language-detection: ' . (microtime(true) - $start) . ' сек.';
// Аналогично для Text_LanguageDetect
?>
patrickschur/language-detection: 0.45 сек.