- HTML Character Sets
- Example
- HTML Character Sets
- In the Beginning: ASCII
- In Windows: Windows-1252
- In HTML 4: ISO-8859-1
- Example
- Example
- Example
- In HTML5: Unicode UTF-8
- Example
- Example
- HTML Unicode (UTF-8) Reference
- The Unicode Character Sets
- The HTML5 Standard: Unicode UTF-8
- Example
- The Difference Between Unicode and UTF-8
- HTML5 UTF-8 Character Codes
- Как преобразовать символы текста в html-сущности в РНР?
- Для чего это может понадобиться?
- Преобразовываем символы в html-сущности в кодировке UTF-8
- Преобразовываем символы в html-сущности в кодировке Windows-1251
- Кодировка HTML-ENTITIES
HTML Character Sets
To display an HTML page correctly, the browser must know what character set (encoding) to use:
Example
HTML Character Sets
The HTML5 specification encourages web developers to use the UTF-8 character set!
This has not always been the case. The character encoding for the early web was ASCII.
Later, from HTML 2.0 to HTML 4.01, ISO-8859-1 was considered as the standard character set.
With XML and HTML5, UTF-8 finally arrived and solved a lot of character encoding problems.
In the Beginning: ASCII
Computer data is stored as binary codes (01000101) in the electronics.
To standardize the storing of text, the American Standard Code for Information Interchange (ASCII) was created. It defined a unique binary number for each storable character to support the numbers from 0-9, the upper and lower case alphabet (a-z, A-Z), and special characters like ! $ + — ( ) @ < >, .
Since ASCII used 7 bits for the character, it could only represent 128 different characters.
The biggest weakness with ASCII, was that it excluded non English letters.
ASCII is still in use today, especially in large mainframe computer systems.
For a closer look, please study our Complete ASCII Reference.
In Windows: Windows-1252
Windows-1252 was the default character set in Windows, up to Windows 95.
It is an extension to ASCII, with added international characters.
It uses a full byte (8-bits) to represent 256 different characters.
Since Windows-1252 has been the default in Windows, it is supported by all browsers.
In HTML 4: ISO-8859-1
The character set most often used in HTML 4 was ISO-8859-1.
ISO-8859-1 is an extension to ASCII, with added international characters.
Example
In HTML 4, a character set different from ISO-8859-1 can be specified in the tag:
Example
All HTML 4 processors also support UTF-8:
Example
When a browser detects ISO-8859-1 it normally defaults to Windows-1252, because Windows-1252 has 32 more international characters.
In HTML5: Unicode UTF-8
The HTML5 specification encourages web developers to use the UTF-8 character set.
Example
A character-set different from UTF-8 can be specified in the tag:
Example
The Unicode Consortium developed the UTF-8 and UTF-16 standards, because the ISO-8859 character-sets are limited, and not compatible a multilingual environment.
The Unicode Standard covers (almost) all the characters, punctuations, and symbols in the world.
All HTML5 and XML processors support UTF-8, UTF-16, Windows-1252, and ISO-8859.
HTML Unicode (UTF-8) Reference
The Unicode Consortium develops the Unicode Standard. Their goal is to replace the existing character sets with its standard Unicode Transformation Format (UTF).
The Unicode Standard has become a success and is implemented in HTML, XML, Java, JavaScript, E-mail, ASP, PHP, etc. The Unicode standard is also supported in many operating systems and all modern browsers.
The Unicode Consortium cooperates with the leading standards development organizations, like ISO, W3C, and ECMA.
The Unicode Character Sets
Unicode can be implemented by different character sets. The most commonly used encodings are UTF-8 and UTF-16:
Character-set | Description |
---|---|
UTF-8 | A character in UTF8 can be from 1 to 4 bytes long. UTF-8 can represent any character in the Unicode standard. UTF-8 is backwards compatible with ASCII. UTF-8 is the preferred encoding for e-mail and web pages |
UTF-16 | 16-bit Unicode Transformation Format is a variable-length character encoding for Unicode, capable of encoding the entire Unicode repertoire. UTF-16 is used in major operating systems and environments, like Microsoft Windows, Java and .NET. |
Tip: The first 128 characters of Unicode (which correspond one-to-one with ASCII) are encoded using a single octet with the same binary value as ASCII, making valid ASCII text valid UTF-8-encoded Unicode as well.
HTML 4 supports UTF-8. HTML 5 supports both UTF-8 and UTF-16!
The HTML5 Standard: Unicode UTF-8
Because the character sets in ISO-8859 were limited in size, and not compatible in multilingual environments, the Unicode Consortium developed the Unicode Standard.
The Unicode Standard covers (almost) all the characters, punctuations, and symbols in the world.
Unicode enables processing, storage, and transport of text independent of platform and language.
The default character encoding in HTML-5 is UTF-8.
If an HTML5 web page uses a different character set than UTF-8, it should be specified in the tag like:
Example
The Difference Between Unicode and UTF-8
Unicode is a character set. UTF-8 is encoding.
Unicode is a list of characters with unique decimal numbers (code points). A = 65, B = 66, C = 67, .
This list of decimal numbers represent the string «hello»: 104 101 108 108 111
Encoding is how these numbers are translated into binary numbers to be stored in a computer:
UTF-8 encoding will store «hello» like this (binary): 01101000 01100101 01101100 01101100 01101111
Encoding translates numbers into binary. Character sets translates characters to numbers.
HTML5 UTF-8 Character Codes
Below is a list of some of the UTF-8 character codes supported by HTML5:
Character codes | Decimal | Hexadecimal |
---|---|---|
C0 Controls and Basic Latin | 0-127 | 0000-007F |
C1 Controls and Latin-1 Supplement | 128-255 | 0080-00FF |
Latin Extended-A | 256-383 | 0100-017F |
Latin Extended-B | 384-591 | 0180-024F |
Spacing Modifiers | 688-767 | 02B0-02FF |
Diacritical Marks | 768-879 | 0300-036F |
Greek and Coptic | 880-1023 | 0370-03FF |
Cyrillic Basic | 1024-1279 | 0400-04FF |
Cyrillic Supplement | 1280-1327 | 0500-052F |
General Punctuation | 8192-8303 | 2000-206F |
Currency Symbols | 8352-8399 | 20A0-20CF |
Letterlike Symbols | 8448-8527 | 2100-214F |
Arrows | 8592-8703 | 2190-21FF |
Mathematical Operators | 8704-8959 | 2200-22FF |
Box Drawings | 9472-9599 | 2500-257F |
Block Elements | 9600-9631 | 2580-259F |
Geometric Shapes | 9632-9727 | 25A0-25FF |
Miscellaneous Symbols | 9728-9983 | 2600-26FF |
Dingbats | 9984-10175 | 2700-27BF |
Как преобразовать символы текста в html-сущности в РНР?
Иногда необходимо, чтобы содержимое html-файла был представлено не символами ( q, r, 6 ,1, а, т, ю, *, ., ? , ну, и т.д.), а так называемыми html-сущностями: < , & , × и т.д.). Кроме того, и обычные символы (буквы, цифры) также можно представить в виде html-сущностей.
Для чего это может понадобиться?
Для представления содержимого файла html исключительно символами, входящими во множество символов ASCII. Например, если на сайте используется кодировка, отличная от UTF-8.
При всей ее удобстве и универсальности, эта кодировка, все-таки, обладает недостатками, как минимум:
Увеличивает объем вебстраницы (в байтах), если она содержит нелатинский шрифт (например, китайский или кириллицу);
Создает сложности при распределении оперативной памяти для размещения строк, так как символы, закодированные в UTF-8 имеют разное количество байт. При этом невозможно определить объем требуемой памяти, исходя только из количества символов в строке;
В силу существования многочисленных некорректных последовательностей символов utf-8, возможна так называемая «атака неверной кодировкой», которая, при отсутствии надлежащих фильтров на сервере, может привести к его «взлому». Ряд программ может завершиться с ошибкой. Наличие некорректной последовательности UTF-8 в коде javascript при обработке его браузером вызывает ошибку.
Все, о чем пойдет речь ниже, протестировано в PHP5.3. Как оно будет работать в более высоких версиях РНР – сказать крайне сложно. Необходимо будет повторять тестирование.
Преобразовываем символы в html-сущности в кодировке UTF-8
Для этого используем функцию htmlentities (РНР):
А вот что на самом деле было прислано браузеру от сервера:
Т.е. преобразовались кавычки, амперсанд и крестик.
Кстати, файл, в котором сохранен этот скрипт, должен быть в кодировке UTF-8. Поэтому и браузеру отсылаем заголовок, в котором указываем ту же самую кодировку. Иначе браузер, скорее всего, неверно отобразит ответ сервера, т.е. отобразит некую абракадабру. Тогда для целей читаемости, придется устанавливать в браузере кодировку вручную.
Как видим, при указании параметра ENT_IGNORE сервер все-таки что-то отвечает браузеру, но не полностью. Такое поведение, конечно, может являться возможностью для реализации уязвимостей. Поэтому этот параметр целесообразно применять, разве что, для целей тестирования, когда заведомо известно, что сервер не получит от клиента (браузера) вредоносного кода, при необходимости вывести полный результат работы сервера. В рабочих вариантах сервера этот параметр применять не следует.
Также видим здесь разницу между одиночными (апострофами) и двойными кавычками в PHP: если одиночные кавычки отображают содержащиеся в них символы в состоянии «как есть», то двойные делают соответствующие преобразования.
Преобразовываем символы в html-сущности в кодировке Windows-1251
Для проверки, попробуем то же самое сделать, используя кодировку Windows-1251 (синоним: cp1251). Для этого отсылаем серверу соответствующий заголовок и соответствующим же образом перекодируем сообщения сервера:
Как видно, символы ア и × выведены в качестве знаков вопроса (т.е. не распознаны). Установка внутренней кодировки скрипта
Если убрать htmlentities, то будет то же самое. При этом, естественно, символ амперсанда ( & ) будет присутствовать на странице именно как & , а не как & , т.е. не будет преобразован.
А вот что будет в самом ответе сервера (посмотреть ответ сервера, например, в браузере Firefox можно, посмотрев исходный код страницы или нажав правую кнопку мыши -> Исследовать элемент -> вкладка Сеть -> Ответ):
Таким образом, в специальные сущности преобразовались только кавычки, амперсанд и кириллица. Ни ア , × – не преобразовались. Что противоречит так называемому «мануалу» (по ссылке, приведенной выше). Вот фраза оттуда:
« htmlentities( ) преобразует все символы в соответствующие HTML-сущности (для тех символов, для которых HTML-сущности существуют)».
Однако, функция htmlentities закодировала только так называемые специальные символы и кириллицу, тогда как ア, × не преобразовались. Хотя сущности для них – существуют.
Если убрать htmlentities из кода, то сервер даст такой ответ:
При этом в браузере на открытой странице ничего не изменится. Теперь кириллица присутствует, как положено. В обычном своем незакодированном виде.
Функция htmlentities работает, как минимум, ЗАВИСИМО от указания кодировки. В случае кодировки UTF-8 кириллица не преобразуется. А вот в случае Windows-1251 – она преобразуется в html-сущности.
Если символ не содержится во множестве кодировки, указанной в качестве параметра в htmlentities, он, видимо, не будет отображен (точнее, вместо него будут отображаться знаки вопроса), что видно на примере кодировки Windows-1251. В «мануале» об этом почему-то речи не идет.
По всей видимости, программист должен телепатически догадаться обо всем этом или лезть в исходные коды функций РНР. Зачем так сделано, и, главное, почему в «мануале» (на который почему-то любят ссылаться на форумах в интернете) об этом нет ни слова – непонятно.
Кодировка HTML-ENTITIES
Это – достаточно редко используемая кодировка , но она есть в РНР. Используется она там не везде. А, например, в функции mb_convert_encoding. Можно попробовать преобразовать строку в эту кодировку:
header( ‘Content-Type: text/html; charset=utf-8’ );
$x = mb_convert_encoding( » ア \» привет hell × $& » . » \x8F 2G» , «HTML-ENTITIES» , «utf-8» ). «
» ;
echo $x ;
А вот что будет наблюдаться в браузере:
Как видно, успешно перекодировались символы кириллицы, а также ア , ×. Результат отличается от результата работы функции htmlentities.
Таким образом, использование функции mb_convert_encoding с кодировкой HTML-ENTITIES предпочтительнее, чем использование функции htmlentities в случае, если необходимо перекодировать символы национального языка (в данном случае – русского) и специальные символы типа × , не трогая служебные символы типа кавычек, амперсанда и т.п.
Причем, результат будет таким же и в случае использования кодировки Windows-1251 или даже в случае, например, кодировки JIS, т.е. когда будет
header( ‘Content-Type: text/html; charset=cp1251’ );
header( ‘Content-Type: text/html; charset=JIS’ );
Напоследок
К сожалению, УВЫ, вот так приходится, что называется, «иметь дело» со многими, если не практически со всеми функциями РНР. В целом-то, да, они как-то там даже работают. Но, чуть специфические условия использования – и всё. Приходится отлаживать, выяснять, насколько приемлем результат.
Так что же, PHP и в самом деле ужасен?
Как сказать… смотря, с чем сравнивать. Если с языком С – то да, конечно. Правда, в отличие от С, у РНР есть одно неоспоримое достоинство: программа, написанная на нем, имеет объем раза в 2…3 меньший, чем аналогичная программа на С. Что же касается порога вхождения – он практически одинаков что в РНР, что в С.
Ну, а если говорить о разных новомодных Haskell, Kotlin, Go, Go! и иже с ними – так, видимо, они не кажутся столь «ужасными» ТОЛЬКО потому, что еще не столь сильно распространены, еще не столь много опыта их использования. В конце концов, еще лет 10…15 назад многие думали, что и операционная система Linux абсолютно защищена от вирусов. РНР-то, по крайней мере, более-менее апробирован и основные ошибки (баги) в нем так или иначе устраняются.