Во-первых, всегда разбейте вашу проблему на более мелкие части, чтобы увидеть, где она идет не так:
$string=html_entity_decode($string, ENT_COMPAT, 'UTF-8');
echo $string, "\n";
$string = trim($string);
echo $string, "\n";
$string = strip_tags($string);
echo $string, "\n";
$string = substr($string, 0, 14);
echo $string, "\n";
Если вы запустите это, вы увидите, что проблема не имеет ничего общего с strip_tags
, она имеет отношение к substr
.
Причина очень проста: строки в PHP - это просто последовательность байтов; такие функции, как substr
не учитывают "символы" каким-либо значимым образом. Так что substr($string, 0, 14)
просто берет первые 14 байтов строки, что в данном случае приводит к разбиению «символа», который был закодирован как более одного байта, с использованием UTF-8.
Наиболее распространенным решением для этого является использование mb_substr
(часть расширения PHP "mbstring"), которое считает "символы" в соответствии с некоторой кодировкой:
$string = mb_substr($string, 0, 14, 'UTF-8');
echo $string, "\n";
// Şelamiİnnşşasd
Обратите внимание, что это будет сокращено до 14 кодовых точек Unicode , поэтому все еще можно делать странные вещи, такие как срезать акцент с буквы, если она была закодирована с использованием "диакритического символа".
Альтернативой в некоторых случаях было бы использование grapheme_substr
(часть расширения "intl"), которое разделяется на "графемы", которые предназначены примерно как то, что люди думают как «символ» или «буква». В этом случае он дает тот же результат:
$string = grapheme_substr($string, 0, 14, 'UTF-8');
echo $string, "\n";
// Şelamiİnnşşasd
Но в других случаях это может быть не так:
$string = 'noël';
echo mb_substr($string, 0, 3, 'UTF-8'), "\n"; // noe
echo grapheme_substr($string, 0, 3), "\n"; // noë