Определение языка текста в PHP: инструменты и примеры

Раздел: PHP обработка текста -> Определение языка текста в 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...)
*/

Пояснение шагов:

  1. Установка библиотеки через Composer.
  2. Подключение автозагрузчика и импорт класса Language.
  3. Создание экземпляра Language (по умолчанию загружаются все языки; можно ограничить список через конструктор).
  4. Метод detect() возвращает объект LanguageResult, который содержит массив языков с вероятностями.
  5. Вызов 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 сек.

Определение языка в PHP - comments

En
определить язык php (php)