strlen () и UTF-8

Предполагая кодировку UTF-8 и strlen () в PHP, возможно ли, что эта строка имеет длину 4?

Мне только интересно узнать о strlen (), а не о других функциях

Это строка: $ 1�2

Я протестировал его на своем собственном компьютере, и я проверил кодировку UTF-8, и ответ, который я получил, – 6.

Я не вижу ничего в руководстве для strlen или что-либо, что я читал на UTF-8, что объясняет, почему некоторые из вышеперечисленных символов будут считаться менее чем одним.

PS: Этот вопрос и ответ (4) исходят из ложного теста для ZCE, который я купил на Ebay.

PPS: Пожалуйста, бросьте мне кость и проголосуйте за нее. Я сделал домашнее задание. Заранее благодарю всех ответов и голосов.

Строка, которую вы разместили, длится шесть символов: $ 1�2 (знак доллара, цифра один, строчный i с диарезисом, знак перевернутого вопроса, одна половина, цифра два)

Если вызов strlen () был вызван с представлением UTF-8 этой строки, вы получите результат из девяти (вероятно, хотя есть несколько представлений с разной длиной).

Однако, если бы мы сохранили эту строку как ISO 8859-1 или CP1252, у нас была бы шестибайтная длинная последовательность, которая была бы законной как UTF-8. Интерпретация этих 6 байтов, как UTF-8, приведет к 4 символам: $ 1 2 (знак доллара, цифра один, символ замены Unicode, цифра 2). То есть кодировка UTF-8 одиночного символа « » идентична кодировке ISO-8859-1 трех символов «ï¿½».

Символ замены часто вводится, когда декодер UTF-8 считывает данные, которые являются недопустимыми данными UTF-8.

Похоже, что исходная строка обрабатывалась несколькими уровнями неправильной интерпретации; с использованием декодера UTF-8 для данных, отличных от UTF-8 (с получением $ 1 2), а затем с помощью того, что вы использовали для анализа этих данных (с получением $ 1 ½½).

как насчет использования mb_strlen ()?

http://lt.php.net/manual/en/function.mb-strlen.php

Но если вам нужно использовать strlen, можно настроить ваш веб-сервер, установив директиву mbstring.func_overload на 2, чтобы он автоматически заменил использование strlen в mb_strlen в ваших сценариях.

необходимо использовать функцию Multibyte String mb_strlen (), например:

 mb_strlen($string, 'UTF-8'); 

Вполне вероятно, что в какой-то момент между подготовкой вопроса и чтением его какой-то процесс искал в нем не-ASCII-символы, поэтому вопрос был первоначально о некоторой строке с 4 символами в ней.

Последовательность � получается при кодировании символа замещения U + FFFD ( ) в UTF-8 и интерпретации результата в latin1. Этот символ используется в качестве замены байтовых последовательностей, которые не кодируют какого-либо символа при чтении текста из файла, например. Вероятно, произошло следующее:

Исходный вопрос, хранящийся в текстовом файле latin1, имел: $1¢2 (вы можете заменить ¢ любым символом, отличным от ASCII)

Файл был прочитан программой, использующей UTF-8. Поскольку байт, соответствующий ¢, не может быть интерпретирован, программа заменила его и прочитала текст $1 2 . Затем этот текст был выписан с использованием UTF-8, в результате $1\xEF\xBF\xBD2 в файле.

Затем идет третья программа, которая читает файл в latin1 и показывает $1�2 .

Нет.

Я буду использовать доказательство в противоречии.

strlen подсчитывает байты, поэтому с strlen из 4 в этой строке должно быть ровно 4 байта .

Для кодирования UTF8 требуется не менее 1 байт на символ .

Мы установили, что:

  1. есть 4 байта
  2. символ представлен не менее чем 1 байт

… но у нас есть 6 персонажей …. что противоречие. Итак, нет.

Тем не менее, не совсем ясно, какой символ задает программное обеспечение для показа (например, веб-браузер), использующее intepret строку. Он может использовать какую-то необычную схему кодирования, где символ может быть представлен менее чем 8 бит. Если это так, то 4 байта могут отображаться как 6 символов. Таким образом, строка может быть utf8, но браузер может решить интерпретировать ее как, скажем, 5-битный набор символов.

Многие символы UTF-8 принимают несколько байтов вместо одного. Вот как сконфигурирован UTF-8 (так вы можете иметь столько символов в одном наборе).

Попробуйте mb_strlen() .