Mb scrub: примеры (PHP)

Функция mb_scrub для обработки некорректных символов
Раздел: Многобайтовые строки
mb_scrub(string $string, ?string $encoding = null): string
Описание функции mb_scrub

Функция mb_scrub входит в состав расширения mbstring и предназначена для "очистки" строки, заменяя недопустимые для указанной кодировки байты на символ замены (по умолчанию знак вопроса '?'). Эта операция гарантирует, что результирующая строка будет корректной в заданной кодировке.

Функция используется при работе с текстом неизвестного или смешанного происхождения, где возможно появление некорректных последовательностей байт. Ее применение позволяет избежать ошибок при дальнейшей обработке строки функциями, чувствительными к корректности кодировки.

Аргументы функции
  • string (обязательный): Входная строка, которую требуется обработать.
  • encoding (необязательный): Кодировка, в которой должна быть интерпретирована входная строка и получен результат. Если параметр не задан или равен null, используется внутренняя кодировка, установленная функцией mb_internal_encoding().
Краткие примеры использования
Пример 1: Базовая очистка строки

Код:

<?php
$str = "Hello\x80World"; // \x80 - недопустимый байт в UTF-8
echo mb_scrub($str, 'UTF-8');
?>

Результат:

Hello?World
Пример 2: Использование внутренней кодировки

Код:

<?php
mb_internal_encoding('UTF-8');
$str = "Привет\x80Мир";
echo mb_scrub($str); // Второй аргумент не указан
?>

Результат:

Привет?Мир
Пример 3: Обработка строки в кодировке ISO-8859-1

Код:

<?php
// В UTF-8 последовательность \xC3\x28 невалидна
$str = "Test\xC3\x28String";
echo mb_scrub($str, 'ISO-8859-1');
?>

Результат:

TestÃ(String
Похожие функции в PHP
  • mb_convert_encoding(): Позволяет конвертировать строку между кодировками, указывая режим обработки ошибок. Более гибкая, но и более сложная в использовании для простой очистки.
  • iconv(): Функция для конвертации кодировок. При установке трансляции //IGNORE или //TRANSLIT также может отбрасывать или заменять недопустимые символы. Требует установки расширения iconv.
  • utf8_encode() / utf8_decode(): Специфичны для конвертации между ISO-8859-1 и UTF-8. Не подходят для работы с другими кодировками и имеют ограниченное применение.

Функцию mb_scrub предпочтительнее использовать, когда нужна простая замена невалидных байтов без изменения целевой кодировки строки. Для сложных сценариев конвертации между кодировками больше подходят mb_convert_encoding или iconv.

Типичные ошибки
Ошибка 1: Передача некорректной кодировки

Если указана неизвестная кодировка, будет сгенерирована ошибка уровня E_WARNING.

Код:

<?php
$result = mb_scrub("test", 'UNKNOWN_ENCODING');
?>

Результат:

PHP Warning:  mb_scrub(): Unknown encoding "UNKNOWN_ENCODING" in ...
Ошибка 2: Ожидание изменения исходной строки

Функция возвращает новую строку, не изменяя исходный аргумент.

Код:

<?php
$original = "Bad\x80String";
$cleaned = mb_scrub($original);
var_dump($original); // Оригинал остался неизменным
var_dump($cleaned);  // Это новая строка
?>

Результат:

string(11) "Bad�String"
string(11) "Bad?String"
История изменений
  • PHP 7.2: Функция mb_scrub была добавлена в расширение mbstring.
  • PHP 8.0: Сигнатура функции изменена. Параметр encoding теперь может принимать значение null. При передаче неверного типа аргумента генерируется ошибка TypeError вместо предупреждения.
  • PHP 8.2: Явных изменений в поведении функции не было.
Расширенные примеры
Пример 1: Фильтрация пользовательского ввода

Очистка данных из формы перед записью в базу данных в кодировке UTF-8.

Код:

Пример php
<?php
// Имитация ввода с некорректным байтом
$userInput = $_POST['comment'] = "Отличный комментарий\xFE!";
$safeForUTF8 = mb_scrub($userInput, 'UTF-8');
// $safeForUTF8 теперь безопасна для обработки
echo $safeForUTF8;
?>

Результат:

Отличный комментарий?!
Пример 2: Пакетная обработка массива строк

Код:

Пример php
<?php
$strings = [
    "Нормальная строка",
    "Сломанная\xC2\x28здесь",
    "Ещё одна\xFFстрока"
];
$cleanedStrings = array_map(fn($str) => mb_scrub($str), $strings);
print_r($cleanedStrings);
?>

Результат:

Array
(
    [0] => Нормальная строка
    [1] => Сломанная?(здесь
    [2] => Ещё одна?строка
)
Пример 3: Работа с бинарными данными как со строкой

При попытке интерпретировать часть бинарных данных (например, из изображения) как текст.

Код:

Пример php
<?php
$binaryData = file_get_contents('small_image.png'); // Первые 20 байт
$asString = substr($binaryData, 0, 20);
$scrubbed = mb_scrub($asString, 'UTF-8');
echo 'Очищено: ', bin2hex($scrubbed), "\n";
?>

Результат (примерный):

Очищено: 89504e470d0a1a0a0000000d49484452??????????
Альтернативы в других языках
Python

Используется метод decode() с параметром обработки ошибок errors='replace'.

Код:

str_bytes = b"Hello\x80World"
result = str_bytes.decode('utf-8', errors='replace')
print(result)  # Hello�World

Результат:

Hello�World
JavaScript (Node.js)

Используется TextDecoder с опцией fatal: false и ignoreBOM: true.

Код:

const buffer = new Uint8Array([72, 101, 108, 108, 111, 128, 87, 111, 114, 108, 100]);
const decoder = new TextDecoder('utf-8', { fatal: false });
const result = decoder.decode(buffer);
console.log(result); // Hello�World

Результат:

Hello�World
MySQL

Используется функция CONVERT() с указанием целевой кодировки. Некорректные символы, как правило, заменяются на знак вопроса.

Код (SQL запрос):

SELECT CONVERT(_binary 'Hello\x80World' USING utf8mb4);

Результат:

Hello?World

Основное отличие mb_scrub заключается в простоте синтаксиса и узкой специализации на "очистке" строки без явной конвертации в другую кодировку.

PHP mb_scrub function comments

En
Mb scrub Description