Mb scrub: примеры (PHP)
mb_scrub(string $string, ?string $encoding = null): stringФункция mb_scrub входит в состав расширения mbstring и предназначена для "очистки" строки, заменяя недопустимые для указанной кодировки байты на символ замены (по умолчанию знак вопроса '?'). Эта операция гарантирует, что результирующая строка будет корректной в заданной кодировке.
Функция используется при работе с текстом неизвестного или смешанного происхождения, где возможно появление некорректных последовательностей байт. Ее применение позволяет избежать ошибок при дальнейшей обработке строки функциями, чувствительными к корректности кодировки.
- string (обязательный): Входная строка, которую требуется обработать.
- encoding (необязательный): Кодировка, в которой должна быть интерпретирована входная строка и получен результат. Если параметр не задан или равен
null, используется внутренняя кодировка, установленная функциейmb_internal_encoding().
Код:
<?php
$str = "Hello\x80World"; // \x80 - недопустимый байт в UTF-8
echo mb_scrub($str, 'UTF-8');
?>Результат:
Hello?World
Код:
<?php
mb_internal_encoding('UTF-8');
$str = "Привет\x80Мир";
echo mb_scrub($str); // Второй аргумент не указан
?>Результат:
Привет?Мир
Код:
<?php
// В UTF-8 последовательность \xC3\x28 невалидна
$str = "Test\xC3\x28String";
echo mb_scrub($str, 'ISO-8859-1');
?>Результат:
TestÃ(String
- mb_convert_encoding(): Позволяет конвертировать строку между кодировками, указывая режим обработки ошибок. Более гибкая, но и более сложная в использовании для простой очистки.
- iconv(): Функция для конвертации кодировок. При установке трансляции
//IGNOREили//TRANSLITтакже может отбрасывать или заменять недопустимые символы. Требует установки расширения iconv. - utf8_encode() / utf8_decode(): Специфичны для конвертации между ISO-8859-1 и UTF-8. Не подходят для работы с другими кодировками и имеют ограниченное применение.
Функцию mb_scrub предпочтительнее использовать, когда нужна простая замена невалидных байтов без изменения целевой кодировки строки. Для сложных сценариев конвертации между кодировками больше подходят mb_convert_encoding или iconv.
Если указана неизвестная кодировка, будет сгенерирована ошибка уровня E_WARNING.
Код:
<?php
$result = mb_scrub("test", 'UNKNOWN_ENCODING');
?>Результат:
PHP Warning: mb_scrub(): Unknown encoding "UNKNOWN_ENCODING" in ...
Функция возвращает новую строку, не изменяя исходный аргумент.
Код:
<?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: Явных изменений в поведении функции не было.
Очистка данных из формы перед записью в базу данных в кодировке UTF-8.
Код:
<?php
// Имитация ввода с некорректным байтом
$userInput = $_POST['comment'] = "Отличный комментарий\xFE!";
$safeForUTF8 = mb_scrub($userInput, 'UTF-8');
// $safeForUTF8 теперь безопасна для обработки
echo $safeForUTF8;
?>Результат:
Отличный комментарий?!
Код:
<?php
$strings = [
"Нормальная строка",
"Сломанная\xC2\x28здесь",
"Ещё одна\xFFстрока"
];
$cleanedStrings = array_map(fn($str) => mb_scrub($str), $strings);
print_r($cleanedStrings);
?>Результат:
Array
(
[0] => Нормальная строка
[1] => Сломанная?(здесь
[2] => Ещё одна?строка
)При попытке интерпретировать часть бинарных данных (например, из изображения) как текст.
Код:
<?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??????????
Используется метод decode() с параметром обработки ошибок errors='replace'.
Код:
str_bytes = b"Hello\x80World"
result = str_bytes.decode('utf-8', errors='replace')
print(result) # Hello�WorldРезультат:
Hello�World
Используется 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
Используется функция CONVERT() с указанием целевой кодировки. Некорректные символы, как правило, заменяются на знак вопроса.
Код (SQL запрос):
SELECT CONVERT(_binary 'Hello\x80World' USING utf8mb4);Результат:
Hello?World
Основное отличие mb_scrub заключается в простоте синтаксиса и узкой специализации на "очистке" строки без явной конвертации в другую кодировку.