Mb substitute character: примеры (PHP)

Использование mb_substitute_character для обработки ошибок кодировки
Раздел: Многобайтовые строки
mb_substitute_character(string|int|null $substitute_character = null): mixed

Функция mb_substitute_character в PHP определяет или возвращает текущий символ замены, используемый при сбое преобразования кодировки в многобайтовых строках. Она применяется в контексте обработки текста, когда символы входной строки не могут быть корректно представлены в целевой кодировке.

Назначение и аргументы

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

  • substitute_character: Определяет символ замены. Может быть строкой, целым числом или null. Допустимые значения:
    • integer: Код символа Unicode (например, 0xFFFD).
    • string: Символ в кодировке UTF-8 (например, '?' или '�').
    • 'long': Использовать кодовую позицию в формате U+XXXX (только для вывода).
    • 'none': Ничего не выводить при ошибке.
    • 'entity': Использовать HTML-сущность (только для вывода).

Если аргумент опущен, функция возвращает текущее значение символа замены.

Краткие примеры использования
Получение текущего символа замены
<?
// Возвращает текущий символ замены
$current = mb_substitute_character();
echo $current; // По умолчанию обычно 63 (символ '?')
?>
63
Установка символа замены числом
<?
// Установка символа замены на Unicode REPLACEMENT CHARACTER (U+FFFD)
mb_substitute_character(0xFFFD);
$result = mb_convert_encoding('\x80', 'UTF-8', 'ASCII');
echo $result;
?>
Установка строкового символа
<?
// Установка символа '?' для замены
mb_substitute_character('?');
$str = mb_convert_encoding('Invalid \x95 byte', 'UTF-8', 'Windows-1251');
echo $str;
?>
Invalid ? byte
Использование режима 'none'
<?
// Ничего не выводить при ошибке
mb_substitute_character('none');
$result = mb_convert_encoding('\x80', 'UTF-8', 'ASCII');
echo 'Результат: ' . $result;
?>
Результат: 
Похожие функции в PHP
iconv

Функции модуля iconv предоставляют возможности преобразования кодировок с параметром //TRANSLIT и //IGNORE для обработки ошибок. В отличие от mb_substitute_character, которая задает глобальное поведение, iconv позволяет управлять обработкой ошибок для каждого вызова.

mbstring.strict_detection

Директива конфигурации mbstring.strict_detection влияет на обнаружение кодировок. При значении Off mbstring пытается использовать 'догадки', что может уменьшить количество ошибок преобразования.

Рекомендации по выбору

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

Типичные ошибки
Неверный тип аргумента

Передача недопустимого типа данных приводит к предупреждению и возврату false.

<?
$result = mb_substitute_character([]);
var_dump($result);
?>
Warning: mb_substitute_character() expects parameter 1 to be string|int|null, array given
bool(false)
Выход за диапазон Unicode

Установка числового значения за пределами допустимого диапазона Unicode (0-0x10FFFF) вызывает ошибку.

<?
mb_substitute_character(0x110000);
?>
Warning: mb_substitute_character(): Unknown character.
Несовместимые строки UTF-8

Передача строки, которая не является корректным UTF-8 символом, также вызывает ошибку.

<?
mb_substitute_character('AB');
?>
Warning: mb_substitute_character(): Unknown character.
Влияние на другие функции

Установка символа замены влияет на все последующие операции mbstring, что может привести к неожиданным результатам в разных частях приложения.

Изменения в версиях PHP
PHP 8.0.0

Тип параметра substitute_character расширен: теперь принимает string|int|null вместо только mixed. Возвращаемый тип также уточнен: string|int|bool. В случае ошибки теперь всегда возвращается false, а не null.

PHP 7.4.0

Добавлена поддержка установки символа замены строкой в кодировке UTF-8. Ранее можно было использовать только целочисленные коды.

Предыдущие версии

В PHP 5.4.0 добавлена возможность использовать строковые значения 'long', 'entity' и 'none' только для получения текущего значения, но не для установки.

Расширенные примеры
Обработка битых данных с HTML-сущностями
<?
// Установка режима 'entity' для вывода HTML-сущностей при ошибках
mb_substitute_character('entity');
$data = 'Строка с \x80 битым байтом';
$converted = mb_convert_encoding($data, 'UTF-8', 'Windows-1251');
echo htmlspecialchars($converted);
?>
Строка с � битым байтом
Использование с разными кодировками
<?
// Настройка символа замены для конвертации между разными кодировками
mb_substitute_character(0x25A0); // Символ черного квадрата
$text = 'Euro symbol: €';
// Пытаемся конвертировать из UTF-8 в ASCII, где нет символа евро
$result = mb_convert_encoding($text, 'ASCII', 'UTF-8');
echo $result;
?>
Euro symbol: ■
Временное изменение символа замены
<?
// Сохранение и восстановление текущего символа замены
$original = mb_substitute_character();

mb_substitute_character('none');
$silent = mb_convert_encoding('\x80\x81', 'UTF-8', 'ASCII');

mb_substitute_character($original);
$normal = mb_convert_encoding('\x80', 'UTF-8', 'ASCII');

echo 'Без вывода: ' . $silent . '\n';
echo 'Обычный режим: ' . $normal;
?>
Без вывода: 
Обычный режим: ?
Работа с функциями mbstring
<?
// Влияние на mb_strcut
mb_substitute_character('?');
$str = 'abcdef';
// Режем строку с пересечением многобайтового символа
$result = mb_strcut($str, 0, 4, 'UTF-8');
echo $result;
?>
abcd
Обработка CSV с битыми символами
<?
// Чтение CSV файла с неизвестной кодировкой
mb_substitute_character(0xFFFD); // Unicode replacement character

$csvData = file_get_contents('data.csv');
$utf8Data = mb_convert_encoding($csvData, 'UTF-8', 'auto');

// Разбор CSV с замененными битыми символами
$lines = str_getcsv($utf8Data, '\n');
foreach ($lines as $line) {
    $fields = str_getcsv($line);
    echo implode(', ', $fields) . '\n';
}
?>
Пример, �, данных
Тест, строки, �
Альтернативы в других языках
Python

В Python параметр errors в методах encode()/decode() и функции str.encode() управляет обработкой ошибок. Доступны значения: 'strict', 'ignore', 'replace', 'xmlcharrefreplace'.

# Python пример
text = 'Привет\x80'.encode('windows-1251', errors='replace')
decoded = text.decode('utf-8', errors='ignore')
print(decoded)
Привет?
JavaScript

В JavaScript объект TextDecoder принимает параметр fatal и ignoreBOM. При fatal: false некорректные последовательности заменяются символом замены (U+FFFD).

// JavaScript пример
const decoder = new TextDecoder('utf-8', { fatal: false });
const bytes = new Uint8Array([0x80, 0x41]);
console.log(decoder.decode(bytes));
�A
MySQL

В MySQL параметры CHARACTER SET и COLLATE определяют поведение при преобразовании. Функция CONVERT() может использовать модификатор USING для преобразования кодировок, а некорректные символы заменяются на символ замены для целевой кодировки.

-- MySQL пример
SELECT CONVERT('Привет' USING latin1);
Privet
Основные отличия

В отличие от PHP, где символ замены настраивается глобально, в Python и JavaScript обработка ошибок задается для каждой операции. MySQL использует поведение, зависящее от кодировки таблицы и сервера.

PHP mb_substitute_character function comments

En
Mb substitute character Set/Get substitution character