Поиск корректной кодировки текста в PHP: обзор инструментов

Раздел: Основы PHP -> Работа со строками в PHP

Определение кодировки строки в PHP: основные подходы

Как надежно определить кодировку строки средствами PHP?

Наиболее эффективное решение - использование функции mb_detect_encoding с явным указанием списка ожидаемых кодировок и включением strict-режима. Такой подход минимизирует ложные срабатывания и повышает точность.


$string = 'Пример текста с кириллицей';
$encodings = ['UTF-8', 'Windows-1251', 'KOI8-R', 'ISO-8859-5'];
$encoding = mb_detect_encoding($string, $encodings, true);
if ($encoding === false) {
    echo 'Кодировка не определена';
} else {
    echo 'Определена кодировка: ' . $encoding;
}

Php заменить слово (замена слова в строке php)

  1. Список кодировок должен включать вероятные варианты в порядке убывания вероятности. Первая подходящая кодировка будет возвращена.
  2. Параметр strict (true) заставляет функцию проверять каждый байт на соответствие правилам кодировки. Для UTF-8 это означает проверку многобайтовых последовательностей.
  3. Если функция возвращает false, строка не соответствует ни одной из перечисленных кодировок.

Типичные проблемы:

  • Не указан список кодировок - используется mb_detect_order по умолчанию, который может не подходить для конкретного текста.
  • Неверный порядок кодировок - например, UTF-8 может быть успешно определён для строки на Windows-1251, если она не содержит запрещённых последовательностей.
  • Строки, состоящие только из ASCII, могут быть одинаково валидны для многих кодировок. В таких случаях требуется дополнительный контекст.

Решение: всегда указывайте строгий порядок и используйте strict режим. Для ASCII-строк можно добавить проверку через mb_check_encoding с разными кодировками.

Как определить кодировку с помощью iconv?

Метод основан на попытке конвертации из предполагаемой кодировки в UTF-8. Если конвертация успешна (без предупреждений), значит кодировка определена верно.


$string = 'Текст в Windows-1251';
$encodings = ['UTF-8', 'Windows-1251', 'KOI8-R'];
$detected = false;
foreach ($encodings as $enc) {
    $converted = @iconv($enc, 'UTF-8//IGNORE', $string);
    if ($converted !== false && strlen($converted) > 0) {
        $detected = $enc;
        break;
    }
}
echo $detected ? 'Определена кодировка: ' . $detected : 'Не удалось определить';

Php определить кодировку (определение кодировки строки в php (mb_detect_encoding))

Проблемы:

  • iconv может молча игнорировать некорректные символы с флагом //IGNORE, что даст ложный успех.
  • Производительность ниже, чем у mb_detect_encoding, так как требуется несколько попыток конвертации.

Как проверить, является ли строка UTF-8?

Проверка на корректность UTF-8 выполняется с помощью регулярного выражения или функции mb_check_encoding.


function isUtf8($string) {
    return mb_check_encoding($string, 'UTF-8');
}
// Альтернатива через preg_match:
function isUtf8Regex($string) {
    return preg_match('//u', $string) === 1;
}

Php размер строки (определение размера строки в php)

Проблема: Обе функции проверяют только валидность UTF-8, но не могут отличить UTF-8 от другой однобайтовой кодировки, если в строке только ASCII.

Как определить кодировку по BOM (Byte Order Mark)?

Для UTF-16 и UTF-32 часто используется BOM. Для UTF-8 BOM необязателен, но иногда встречается.


function detectEncodingByBom($string) {
    $bom = substr($string, 0, 4);
    $bomMap = [
        "\xEF\xBB\xBF" => 'UTF-8',
        "\xFF\xFE"     => 'UTF-16LE',
        "\xFE\xFF"     => 'UTF-16BE',
        "\xFF\xFE\x00\x00" => 'UTF-32LE',
        "\x00\x00\xFE\xFF" => 'UTF-32BE'
    ];
    foreach ($bomMap as $bomBytes => $enc) {
        if (strncmp($string, $bomBytes, strlen($bomBytes)) === 0) {
            return $enc;
        }
    }
    return false;
}

Php первое слово (первое слово в строке php)

Проблема: Большинство современных текстов не содержат BOM. Этот метод подходит только как дополнительный.

Как использовать mb_detect_order для глобальной настройки?

Можно установить порядок кодировок для всех вызовов mb_detect_encoding без явного указания параметра.


mb_detect_order(['UTF-8', 'Windows-1251', 'KOI8-R', 'ISO-8859-5']);
$encoding = mb_detect_encoding($string, null, true);
// или просто mb_detect_encoding($string);

Проблема: Глобальная настройка может конфликтовать с другими частями приложения.

Расширенные примеры определения кодировки

Пример 1. Определение кодировки среди 4 вероятных вариантов с выводом результата

Пример

$strings = [
    'Это UTF-8 текст',
    iconv('UTF-8', 'Windows-1251', 'Текст ASCII и кириллица'),
    iconv('UTF-8', 'KOI8-R', 'Другой тест'),
    'Just ASCII'
];

$encodings = ['UTF-8', 'Windows-1251', 'KOI8-R', 'ISO-8859-5'];

foreach ($strings as $str) {
    $detected = mb_detect_encoding($str, $encodings, true);
    echo 'Исходная строка: ' . bin2hex($str) . ' => ' . ($detected ? $detected : 'не определена') . "\n";
}
Исходная строка: d0a2d0b5d0bad181d18220d0bdd0b0... => UTF-8
Исходная строка: ccef20d2e5eaf1f2... => Windows-1251
Исходная строка: f0d2c1d2c5d2c1d2c5... => KOI8-R
Исходная строка: 4a757374204153434949 => не определена (только ASCII)

Пример 2. Детектирование кодировки при загрузке файла

Пример

$fileContent = file_get_contents('data.txt');
$encodings = ['UTF-8', 'Windows-1251', 'KOI8-R', 'ISO-8859-5'];
$detected = mb_detect_encoding($fileContent, $encodings, true);
if ($detected && $detected !== 'UTF-8') {
    $converted = mb_convert_encoding($fileContent, 'UTF-8', $detected);
    file_put_contents('data_utf8.txt', $converted);
    echo 'Файл сконвертирован из ' . $detected . ' в UTF-8';
} else {
    echo 'Кодировка определена как ' . ($detected ?: 'неизвестна');
}

Пример 3. Перебор всех доступных кодировок с помощью mb_list_encodings

Пример

$allEncodings = mb_list_encodings();
$string = 'Строка с неизвестной кодировкой';
$candidates = [];
foreach ($allEncodings as $enc) {
    if (mb_check_encoding($string, $enc)) {
        $candidates[] = $enc;
    }
}
echo 'Строка валидна для следующих кодировок: ' . implode(', ', array_slice($candidates, 0, 5));
Строка валидна для следующих кодировок: UTF-8, Windows-1251, KOI8-R, ISO-8859-5, ISO-8859-1

Пример 4. Верификация найденной кодировки через mb_convert_encoding и сравнение

Пример

function verifyEncoding($string, $enc) {
    $converted = mb_convert_encoding($string, 'UTF-8', $enc);
    return mb_check_encoding($converted, 'UTF-8');
}

$string = "\xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82"; // Привет в UTF-8
$guess = mb_detect_encoding($string, ['UTF-8', 'Windows-1251'], true);
if ($guess && verifyEncoding($string, $guess)) {
    echo 'Кодировка подтверждена: ' . $guess;
}

Пример 5. Обработка массива строк и перевод всех в UTF-8

Пример

$rows = [
    'Запись 1',
    iconv('UTF-8', 'Windows-1251', 'Вторая строка'),
    iconv('UTF-8', 'KOI8-R', 'Третья')
];
$encodings = ['UTF-8', 'Windows-1251', 'KOI8-R'];
$result = [];
foreach ($rows as $row) {
    $detected = mb_detect_encoding($row, $encodings, true);
    if ($detected && $detected !== 'UTF-8') {
        $row = mb_convert_encoding($row, 'UTF-8', $detected);
    }
    $result[] = $row;
}
print_r($result);
Array
(
    [0] => Запись 1
    [1] => Вторая строка
    [2] => Третья
)

Определение кодировки строки в PHP (mb_detect_encoding) - comments

En
Php определить кодировку (php)