str_replace может безопасно использоваться на UTF-8 закодированная строка, если это только дало закодированные строки допустимого UTF-8 как аргументы?

PHP's str_replace() был предназначен только для строк ANSI, и как таковой может исказить строки UTF-8. Однако, учитывая, что двоично-безопасно, что это работало бы правильно, если бы этому только дали допустимые строки UTF-8 как аргументы?

Править: Я не ищу заменяющую функцию, я был бы точно так же, как, чтобы знать, корректна ли эта гипотеза.

22
задан Kevin 29 November 2011 в 19:49
поделиться

4 ответа

Да. UTF-8 специально разработан, чтобы разрешить эту и другую подобную обработку, не поддерживающую Unicode.

В UTF-8 любая последовательность байтов, отличная от ASCII, представляющая допустимый символ, всегда начинается с байта в диапазоне \ xC0- \ xFF . Этот байт может не отображаться где-либо еще в последовательности, поэтому вы не можете создать действительную последовательность UTF-8, которая соответствует части символа.

Это не относится к старым многобайтовым кодам, в которых разные части байтовой последовательности неотличимы. Это вызвало множество проблем, например, при попытке заменить обратную косую черту ASCII в строке Shift-JIS (где байт \ x5C может быть вторым байтом последовательности символов, представляющей что-то еще).

19
ответ дан 29 November 2019 в 05:31
поделиться

Да, я думаю, это правильно, по крайней мере, я не смог найти никакого контрпримера.

0
ответ дан 29 November 2019 в 05:31
поделиться

Это правильно, потому что многобайтовые символы UTF-8 являются исключительно символами не ASCII (128+ байтов) и начинаются с байта, который определяет, сколько байтов следует за ним, поэтому вы не можете случайно сопоставить часть одного многобайтового символа UTF-8 с другим.

Для визуализации (абстрактно):

  • a для символа ASCII
  • 2x для 2-байтового символа
  • 3xx для 3-байтового символа
  • 4xxx для 4-байтового символа

Если вы сопоставляете, скажем, a2x3xx ( a байтов в диапазоне ASCII), поскольку a < x и 2x не могут быть подмножеством 3xx или 4xxx и т. Д., Вы можете быть уверены, что ваш UTF-8 будет совпадают правильно, при условии, что все строки определенно допустимы в кодировке UTF-8.

Изменить: см. Ответ bobince для менее абстрактного объяснения.

5
ответ дан 29 November 2019 в 05:31
поделиться

Ну, у меня есть контрпример: У меня есть файл настроек ".ini" в кодировке UTF8, определяющий настройки приложения, такие как имя отправителя электронной почты. там написано что-то вроде:

email_from = Märta

и я считываю его оттуда в переменную $sender. Теперь, когда я заменяю тело сообщения (снова UTF8)

regards {sender}

$message = str_replace("{sender}",$sender_name,$message);

Письмо абсолютно корректно во всех отношениях, но отправитель полностью сломан. Есть и другие случаи (например, explode() ), когда что-то идет не так со строкой UTF. До преобразования она здорова, но не после него. К сожалению, исправить такое поведение, похоже, невозможно.

Edit: На самом деле, explode() участвует в разборе .ini файла, так что проблема может заключаться именно в этой функции, поэтому str_replace() вполне может быть невиновен.

1
ответ дан 29 November 2019 в 05:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: