Предполагая кодировку 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 байт на символ .
Мы установили, что:
… но у нас есть 6 персонажей …. что противоречие. Итак, нет.
Тем не менее, не совсем ясно, какой символ задает программное обеспечение для показа (например, веб-браузер), использующее intepret строку. Он может использовать какую-то необычную схему кодирования, где символ может быть представлен менее чем 8 бит. Если это так, то 4 байта могут отображаться как 6 символов. Таким образом, строка может быть utf8, но браузер может решить интерпретировать ее как, скажем, 5-битный набор символов.
Многие символы UTF-8 принимают несколько байтов вместо одного. Вот как сконфигурирован UTF-8 (так вы можете иметь столько символов в одном наборе).
Попробуйте mb_strlen()
.