htmlspecialchars — Преобразует специальные символы в HTML сущности


Содержание

htmlspecialchars()

Синтаксис:

htmlspecialchars(string[, flags[, charset[, double_encode]]])

Поддерживается следующими версиями PHP:

Описание функции:

Функция htmlentities() преобразует символы &,»»,», в HTML сущности. Возвращает преобразованную строку.

Обязательный аргумент. Строка которая будет отконвертировона

Необязательный аргумент. Флаг определяет как будут обрабатываться двойные и одинарные кавычки.

ENT_COMPAT — конвертируются двойные кавычки, а одинарные остаются без изменений (используется по умолчанию);

ENT_QUOTES — конвертируются двойные и одинарные кавычки;

ENT_NOQUOTES — любые кавычки не конвертируются;

ENT_IGNORE — если есть неверный код, то он отбрасавется. Без этого флага возвращается пустая строка (добавлено в версии 5.3). Этот флаг добавлен для обратной совместимости. Избегайте его использование, так как это может повлиять на безопасность.

Необязательный аргумент. Определяет кодировку, используемую при преобразовании. Поддерживаются следующие кодировки:

ISO-8859-1, ISO-8859-15, UTF-8, cp866, cp1251, cp1252, KOI8-R, BIG5, GB2312, BIG5-HKSCS, Shift_JIS, EUC-JP

Если ни одна из выше перечисленных кодировок не поддерживаются, то по умолчанию применяется ISO-8859-1

string double_encode Необязательный аргумент. Если double_encode отключен, то преобразования html-етгов не происходит. По умолчанию преобразуется всё. bool

Производятся следующие преобразования:

Примеры:

Пример 1:

$a = «Руководство по PHP»;
echo «Строка без обработки : «.$a;
echo «
«;
htmlspecialchars(«Руководство по PHP», ENT_QUOTES);
echo «Строка с обработкой: «.htmlspecialchars($a);
?>

Строка без обработки : Руководство по PHP
Строка с обработкой: Руководство по PHP

Код HTML страницы будет выглядеть следующим образом:

Строка без обработки : Руководство по PHP
Строка с обработкой: Руководство по PHP

Разница между htmlentities и htmlspecialchars в PHP

В чем разница между функциями htmlentities() и htmlspecialchars() в PHP?

Для начала htmlspecialchars() является подмножеством htmlentities().

В то время как htmlentities преобразует «все применимые символы в HTML-объекты», htmlspecialchars() преобразует только символы ниже:

как указано в руководстве по PHP.

Обе функции используются для «вывода», чтобы обезопасить веб-страницу от атак с использованием межсайтовых сценариев. Однако в книге Essential PHP Security говорится…

«Htmlentities() — лучшая экранирующая функция для экранирования данных, отправляемых клиенту».

Используйте флаг ENT_QUOTES и кодировку UTF-8, как ниже в примере

Флаг ENT_QUOTES указывает ему преобразовывать как двойные, так и одинарные кавычки.

И на заметку, параметры двух функций идентичны.

Где нужно использовать htmlspecialchars()?

Где нужно/можно использовать htmlspecialchars() ?


  1. Когда добавляем инфо в базу?
  2. Когда выводим из базы?

В каком виде нужно хранить информацию в базе?

Илон Маск рекомендует:  Что такое код alter database

И еще один вопрос — если у меня в базе есть текст, но он в следующем формате

Если использовать htmlspecialchars() на этом тексте, то он выводиться как в html редакторе (включая тэги). Как можно использовать htmlspecialchars() в данном случае?

3 ответа 3

htmlspecialchars() используется для предотвращения вставки нежелательного HTML кода в страницу, например, из формы комментирования или обратной связи, путем замены таких символов, как » «,»&» и тд на их HTML-эквиваленты &amp и тд. Тоесть, если вы храните в базе свой HTML-код (код, в котором вы уверены, то его обрабатывать не нужно).

При добавлении информации в базу применять функцию эффективней, так как вы измените строку только один раз при вставке, а затем будете выводить уже обработанную на сайт. Хотя, конечно, можно необработанную строку при выводе пропускать через htmlspecialchars(), но на каждый вывод информации, получаете вызов функции (небольшая, но все-таки потеря производительности).

htmlspecialchars — преобразует спецсимволы в HTML-сущности

Функция htmlspecialchars — преобразует специальные символы в HTML-сущности.

Данная функция используется если нужно вывести в броузере какой-то код как текст(чтобы он не отрабатывался). Синтаксис функции:

Где $string — строка в которой следует преобразовать символы, flags — необязательный аргумент-константа, задающая режим преобразования кавычек.

  • ENT_COMPAT — Преобразует двойные кавычки, одинарные кавычки не изменяются.
  • ENT_QUOTES — Преобразует и двойные и одинарные кавычки.
  • ENT_NOQUOTES — Оставляет без изменения и двойные, и одинарные кавычки.
  • ENT_IGNORE — Отбрасывает некорректные кодовые последовательности вместо возврата пустой строки. Данная возможность предоставляется в целях обратной совместимости, не стоит ей пользоваться без серьезной нужды, т.к. она может внести уязвимости в ваш код.
  • ENT_SUBSTITUTE — Заменяет некорреткные кодовые последовательности символом замены Юникода U+FFFD в случае использования UTF-8 и при использовании другой кодировки, вместо возврата пустой строки.
  • ENT_DISALLOWED — Заменяет кодовые последовательности, несоответствующие указанному типу документа символом замены Юникода U+FFFD в случае использования UTF-8 и при использовании другой кодировки.
  • ENT_HTML401 — Обработка кода в соответствии с HTML 4.01.
  • ENT_XML1 — Обработка кода в соответствии с XML 1.
  • ENT_XHTML — Обработка кода в соответствии с XHTML.
  • ENT_HTML5 — Обработка кода в соответствии с HTML 5.

По умолчанию используется ENT_COMPAT. Константы представляют битовые маски и позволяют передать через один параметр функций несколько значений. Для этого константы следует объеденить их оператором | .

Необязательный аргумент charset определяет кодировку, используемую при конвертации символов.

Если не указан, то значением по умолчанию для него зависит от используемой версии PHP. Хотя это и не обязательный технически аргумент, рекомендуется всегда его указывать.

Функция Htmlspecialchars

Функция Htmlspecialchars преобразует специальные символы в HTML-сущности.
Для сохранения значений HTML сущностей необходимо преобразовать некоторые символы, которые имеют особый смысл. Для этого используйте функцию Htmlspecialchars, которая производит преобразования сисвола & в &, двойных кавычкек в «, одинарных кавычек в или , символ в >.

Параметр String должен содержать конвертируемую строку (string).

Параметр Flags являет собой битовую маску флагов, определяющих режим обработки кавычек, некорректных кодовых последовательностей и используемый тип документа. По умолчанию используется ENT_COMPAT | ENT_HTML401.

Доступные значения параметра Flags:

ENT_COMPAT — Преобразует двойные кавычки, одинарные кавычки не изменяются.

ENT_QUOTES — Преобразует как двойные, так и одинарные кавычки.

ENT_NOQUOTES — Оставляет без изменения как двойные, так и одинарные кавычки.

ENT_IGNORE — Без всяких уведомительных сообщений отбрасывает некорректные кодовые последовательности вместо возврата пустой строки.

ENT_SUBSTITUTE — Заменяет некорректные кодовые последовательности символом замены Юникода U+FFFD в случае использования UTF-8 или � при использовании другой кодировки, вместо возврата пустой строки.

ENT_DISALLOWED — Заменяет неверные коды символов для заданного типа документа символом замены юникода U+FFFD (UTF-8) или � (при использовании другой кодировки) вместо того, чтобы оставлять все как есть.

ENT_HTML401 — Обработка кода в соответствии с HTML 4.01.

ENT_XML1 — Обработка кода в соответствии с XML 1.

ENT_XHTML — Обработка кода в соответствии с XHTML.

ENT_HTML5 — Обработка кода в соответствии с HTML 5.

Необязательный Encoding определяет кодировку, используемую при конвертации символов.

Значением по умолчанию для Encoding зависит от используемой версии PHP. Более ранние версии PHP используют ISO-8859-1. В PHP 5.4 и 5.5 используется UTF-8 по умолчанию. В PHP 5.6 и старше, для значения по умолчанию используется конфигурационная опция Default_charset.

Замечание: Остальные кодировки не поддерживаются, вместо них будет применена кодировка по умолчанию и сгенерировано предупреждение.


Если параметр Double_encode выключен, то PHP не будет преобразовывать существующие html-сущности. По умолчанию преобразуется все без ограничений.

Функция Htmlspecialchars возвращает преобразованную строку (string).

Если входная строка String содержит неверную последовательность символов в указанной кодировке Encoding, то будет возвращаться пустая строка в случае, если флаги ENT_IGNORE или ENT_SUBSTITUTE не установлены.

htmlspecialchars

htmlspecialchars — Преобразует специальные символы в HTML сущности

Описание

В HTML некоторые символы имеют специальное значение и для сохранения своего значения должны быть преобразованы в HTML сущности. Эта функция возвращает строку, над которой проведены некоторые из таких преобразований. Этих преобразований достаточно для большинства задач веб-программирования. Если вам нужно преобразовать все возможные сущности, используйте htmlentities().

Эта функция полезна при отображении данных, введенных пользователем, которые могут содержать нежелательные HTML тэги, например в форуме или гостевой книге. Необязательный второй аргумент quote_style определяет режим обработки одиночных и двойных кавычек. В режиме по умолчанию, ENT_COMPAT, преобразуются двойные кавычки, одиночные остаются без изменений. В режиме ENT_QUOTES преобразуются и двойные, и одиночные кавычки. а в режиме ENT_NOQUOTES и двойные, и одиночные кавычки остаются без изменений.

Производятся следующие преобразования:

  • ‘&’ (амперсанд) преобразуется в ‘&’
  • ‘»‘ (двойная кавычка) преобразуется в ‘»‘ when ENT_NOQUOTES is not set.
  • »’ (одиночная кавычка) преобразуется в »’ только в режиме ENT_QUOTES.
  • ‘>’ (знак «больше чем») преобразуется в ‘>’

Пример #1 Пример использования htmlspecialchars()

Обратите внимание, что функция не производит других преобразований кроме описанных выше. Для преобразования всех HTML сущностей используйте htmlentities(). Поддержка необязательного второго аргумента была добавлена в PHP 3.0.17 и PHP 4.0.3.

Необязательный третий аргумент charset определяет кодировку, используемую при преобразовании. По умолчанию используется кодировка ISO-8859-1. Поддержка этого аргумента была добавлена в PHP 4.1.0.

Начиная с PHP 4.3.0 поддерживаются следующие кодировки.

Поддерживаемые кодировки
Кодировка Псевдонимы Описание
ISO-8859-1 ISO8859-1 Западно-европейская Latin-1
ISO-8859-15 ISO8859-15 Западно-европейская Latin-9. Добавляет знак евро, французские и финские буквы к кодировке Latin-1(ISO-8859-1).
UTF-8 8-битная Unicode, совместимая с ASCII.
cp866 ibm866, 866 Кириллическая кодировка, применяемая в DOS. Поддерживается в версии 4.3.2.
cp1251 Windows-1251, win-1251, 1251 Кириллическая кодировка, применяемая в Windows. Поддерживается в версии 4.3.2.
cp1252 Windows-1252, 1252 Западно-европейская кодировка, применяемая в Windows.
KOI8-R koi8-ru, koi8r Русская кодировка. Поддерживается в версии 4.3.2.
BIG5 950 Традиционный китайский, применяется в основном на Тайване.
GB2312 936 Упрощенный китайский, стандартная национальная кодировка.
BIG5-HKSCS Расширенная Big5, применяемая в Гонг-Конге.
Shift_JIS SJIS, 932 Японская кодировка.
EUC-JP EUCJP Японская кодировка.

Замечание: Не перечисленные выше кодировки не поддерживаются, и вместо них применяется ISO-8859-1.

Коментарии

Actually, if you’re using >= 4.0.5, this should theoretically be quicker (less overhead anyway):

also see function «urlencode()», useful for passing text with ampersand and other special chars through url

(i.e. the text is encoded as if sent from form using GET method)

and if the link is followed, the $_GET[«text»] in foo.php will contain «foo?&bar!»

I was recently exploring some code when I saw this being used to make data safe for «SQL».

This function should not be used to make data SQL safe (although to prevent phishing it is perfectly good).

Here is an example of how NOT to use this function:

= htmlspecialchars ( trim ( «$_POST[username]» ));

$uniqueuser = $realm_db -> query ( «SELECT `login` FROM `accounts` WHERE `login` = ‘$username'» );
?>

(Only other check on $_POST[‘username’] is to make sure it isn’t empty which it is after trim on a white space only name)

The problem here is that it is left to default which allows single quote marks which are used in the sql query. Turning on magic quotes might fix it but you should not rely on magic quotes, in fact you should never use it and fix the code instead. There are also problems with \ not being escaped. Even if magic quotes were used there would be the problem of allowing usernames longer than the limit and having some really weird usernames given they are to be used outside of html, this just provide a front end for registering to another system using mysql. Of course using it on the output wouldn;t cause that problem.

Another way to make something of a fix would be to use ENT_QUOTE or do:

= $realm_db -> query ( ‘SELECT `login` FROM `accounts` WHERE `login` = «‘ . $username . ‘»;’ );
?>

Eitherway none of these solutions are good practice and are not entirely unflawed. This function should simply never be used in such a fashion.

I hope this will prevent newbies using this function incorrectly (as they apparently do).

if your goal is just to protect your page from Cross Site Scripting (XSS) attack, or just to show HTML tags on a web page (showing on the page, for example), then using htmlspecialchars() is good enough and better than using htmlentities(). A minor point is htmlspecialchars() is faster than htmlentities(). A more important point is, when we use htmlspecialchars($s) in our code, it is automatically compatible with UTF-8 string. Otherwise, if we use htmlentities($s), and there happens to be foreign characters in the string $s in UTF-8 encoding, then htmlentities() is going to mess it up, as it modifies the byte 0x80 to 0xFF in the string to entities like é. (unless you specifically provide a second argument and a third argument to htmlentities(), with the third argument being «UTF-8»).

The reason htmlspecialchars($s) already works with UTF-8 string is that, it changes bytes that are in the range 0x00 to 0x7F to

Just a few notes on how one can use htmlspecialchars() and htmlentities() to filter user input on forms for later display and/or database storage.

1. Use htmlspecialchars() to filter text input values for html input tags. i.e.,

2. Use htmlentities() to filter the same data values for most other kinds of html tags, i.e.,


3. Use your database escape string function to filter the data for database updates & insertions, for instance, using postgresql,

pg_query($connection,»UPDATE datatable SET datavalue='».pg_escape_string($data).»‘»);

This strategy seems to work well and consistently, without restricting anything the user might like to type and display, while still providing a good deal of protection against a wide variety of html and database escape sequence injections, which might otherwise be introduced through deliberate and/or accidental input of such character sequences by users submitting their input data via html forms.

This may seem obvious, but it caused me some frustration. If you try and use htmlspecialchars with the $charset argument set and the string you run it on is not actually the same charset you specify, you get any empty string returned without any notice/warning/error.

= «A valid UTF-8 string» ;
$bad_utf8 = «An invalid UTF-8 string» ;

var_dump ( htmlspecialchars ( $bad_utf8 , ENT_NOQUOTES , ‘UTF-8’ )); // string(0) «»

var_dump ( htmlspecialchars ( $ok_utf8 , ENT_NOQUOTES , ‘UTF-8’ )); // string(20) «A valid UTF-8 string»

?>

So make sure your charsets are consistent

= «An invalid UTF-8 string» ;

// make sure it’s really UTF-8
$bad_utf8 = mb_convert_encoding ( $bad_utf8 , ‘UTF-8’ , mb_detect_encoding ( $bad_utf8 ));

var_dump ( htmlspecialchars ( $bad_utf8 , ENT_NOQUOTES , ‘UTF-8’ )); // string(23) «An invalid UTF-8 string»

?>

I had this problem because a Mac user was submitting posts copy/pasted from a program and it contained weird chars in it.

I had problems with spanish special characters. So i think in using htmlspecialchars but my strings also contain HTML.
So I used this :) Hope it help

function htmlspanishchars ( $str )
<
return str_replace (array( » , «>» ), array( » , «>» ), htmlspecialchars ( $str , ENT_NOQUOTES , «UTF-8» ));
>
?>

i searched for a while for a script, that could see the difference between an html tag and just placed in the text,
the reason is that i recieve text from a database,
wich is inserted by an html form, and contains text and html tags,
the text can contain , so does the tags,
with htmlspecialchars you can validate your text to XHTML,
but you’ll also change the tags, like to ,
so i needed a script that could see the difference between those two.
but i couldn’t find one so i made my own one,
i havent fully tested it, but the parts i tested worked perfect!
just for people that were searching for something like this,
it may looks big, could be done easier, but it works for me, so im happy.

function fixtags ( $text ) <
$text = htmlspecialchars ( $text );
$text = preg_replace ( «/=/» , «=\»\»» , $text );
$text = preg_replace ( «/»/» , «»\»» , $text );
$tags = «/ /i» ;
$replacement = » » ;
$text = preg_replace ( $tags , $replacement , $text );
$text = preg_replace ( «/=\»\»/» , «=» , $text );
return $text ;
>
?>

an example:

= »
this is smaller than this

this is the same = as this

Bold italic etc. » ;
echo fixtags ( $string );
?>

will echo:
this is smaller than this

this is the same = as this

I hope its helpfull!!

Unfortunately, as far as I can tell, the PHP devs did not provide ANY way to set the default encoding used by htmlspecialchars() or htmlentities(), even though they changed the default encoding in PHP 5.4 (*golf clap for PHP devs*). To save someone the time of trying it, this does not work:

( ‘default_charset’ , $charset ); // doesn’t work.
?>

Unfortunately, the only way to not have to explicitly provide the second and third parameter every single time this function is called (which gets extremely tedious) is to write your own function as a wrapper:

( ‘CHARSET’ , ‘ISO-8859-1’ );
define ( ‘REPLACE_FLAGS’ , ENT_COMPAT | ENT_XHTML );

function html ( $string ) <
return htmlspecialchars ( $string , REPLACE_FLAGS , CHARSET );
>

echo html ( «ñ» ); // works
?>

You can do the same for htmlentities()

In many PHP legacy products the function htmlspecialchars($string) is used to convert characters like and quotes a.s.o to HTML-entities. That avoids the interpretation of HTML Tags and asymmetric quote situations.

Since PHP 5.4 for $string in htmlspecialchars($string) utf8 characters are expected if no charset is defined explicitly as third parameter in the function. Legacy products are mostly in Latin1 (alias iso-8859-1) what makes the functions htmlspecialchars(), htmlentites() and html_entity_decode() to return empty strings if a special character, e. g. a German Umlaut, is present in $string:

As of PHP 5.4 they changed default encoding from «ISO-8859-1» to «UTF-8». So if you get null from htmlspecialchars or htmlentities

where you have only set
echo htmlspecialchars ( $string );
echo htmlentities ( $string );
?>

you can fix it by
echo htmlspecialchars ( $string , ENT_COMPAT , ‘ISO-8859-1’ , true );
echo htmlentities ( $string , ENT_COMPAT , ‘ISO-8859-1’ , true );
?>

On linux you can find the scripts you need to fix by

grep -Rl «htmlspecialchars\\|htmlentities» /path/to/php/scripts/

For those having problems after the change of default value of $encoding argument to UTF-8 since PHP 5.4.

If your old non-UTF8 projects ruined — pls consider:
1. function.override-function
2. http://php.net/manual/ru/function.runkit-function-redefine.php

The idea — you override the built-in htmlspecialchars() function with your customized variant which is able to respect non UTF-8 default encoding. This small piece of code can be then easily inserted somewhere at the start of yout project. No need to rewrite all htmlspecialchars() entries globally.


I’ve spent several hours with both approaches. Variant 1 looks good especaially in combination with function.rename-function as it allows to call original htmlspecialchars() with just altered default args. The code could be as follows:

( ‘htmlspecialchars’ , ‘renamed_htmlspecialchars’ );
function overriden_htmlspecialchars ( $string , $flags = NULL , $encoding = ‘cp1251’ , $double_encode = true ) <
$flags = $flags ? $flags : ( ENT_COMPAT | ENT_HTML401 );
return renamed_htmlspecialchars ( $string , $flags , $encoding , $double_encode );
>
override_function ( ‘htmlspecialchars’ , ‘$string, $flags, $encoding, $double_encode’ , ‘return overriden_htmlspecialchars($string, $flags, $encoding, $double_encode);’ );
?>

Unfortunatelly this didn’t work for me properly — my site managed to call overriden function but not every time I reloaded the pages. Moreover other PHP sites crashed under my Apache server as they suddenly started blaming htmlspecialchars() was not defined. I suppose I had to spend more time to make it work thread/request/site/whatever-safe.

So I switched to runkit (variant 2). It worked for me, although even after trying runkit_function_rename()+runkit_function_add() I didn’t managed to recall original htmlspecialchars() function. So as a quick solution I decided to call htmlentities() instead:

function overriden_htmlspecialchars ( $string , $flags = NULL , $encoding = ‘UTF-8’ , $double_encode = true ) <
$flags = $flags ? $flags : ( ENT_COMPAT | ENT_HTML401 );
$encoding = $encoding ? $encoding : ‘cp1251’ ;
return htmlentities ( $string , $flags , $encoding , $double_encode );
>
runkit_function_redefine ( ‘htmlspecialchars’ , ‘$string, $flags, $encoding, $double_encode’ , ‘return overriden_htmlspecialchars($string, $flags, $encoding, $double_encode);’ );
?>

You may be able to implement your more powerfull overriden function.
Good luck!

Be aware of the encoding of your source files.

Some of the suggestions here make reference to workarounds where you hard-code an encoding.

echo htmlspecialchars ( ‘Wörmann‘ ); // Why isn’t this working?
?>

As it turns out, it may actually be your text editor that is to blame.

As of PHP 5.4, htmlspecialchars now defaults to the UTF-8 encoding. That said, many text editors default to non-UTF encodings like ISO-8859-1 (i.e. Latin-1) or WIN-1252. If you change the encoding of the file to UTF-8, the code above will now work (i.e. the ö is encoded differently in UTF-8 and ISO-8859-1, and you need the UTF-8 version).

Make sure you are editing in UTF-8 Unicode mode! Check your UI or manual for how to convert files to Unicode. It’s also a good idea to figure out where to look in your UI to see what the current file encoding is.

If you use htmlspecialchars() to escape any HTML attribute, make sure use double quote instead of single quote for the attribute.

> Wrap with Single Quote
echo «

// title will end up Hello»s\ and rest of the text after single quote will be cut off.
?>

> Wrap with Double quote :
echo ‘

// title will show up correctly as Hello»s’world
?>

Улучшения в htmlspecialchars() в версии 5.4

Вокруг новых фич в PHP 5.4 было много разговоров, как например про traits, короткий синтаксис массивов.

Но одни особенно важные изменения, которые часто забывают для PHP 5.4, героически переписал cataphract (Artefacto на StackOverflow) большую часть htmlspecialchars.

Изменения о которых идет речь, относятся не только к htmlspecialchars, но еще и к htmlentities, htmlspecialchars_decode, html_entity_decode, get_html_translation_table.

Вот краткий обзор наиболее важных изменений:

  • UTF-8 кодировка по-умолчанию
  • Улучшенная обработка ошибок (ENT_SUBSTITUTE)
  • Обработка Doctype (ENT_HTML401, …)

UTF-8 кодировка по умолчанию

Как вы знаете, третий аргумент для htmlspecialchars это кодировка. Большинство людей просто упускают этот аргумент, таким образом, получая кодировку по умолчанию. Это значение было ISO-8859-1 до PHP 5.4. Новая версия исправляет это, сделав UTF-8 по умолчанию.

Улучшенная обработка ошибок

Обработка ошибок в htmlspecialchars до 5.4 была… хм, назовем ее «неинтуитивной»:

Если вы указали строку содержащую «некорректную кодовую последовательность» (для Unicode это «некоректно закодированя строка») htmlspecialchars вернет пустую строку. Ну, ладно, пока все хорошо. Забавно то, что она дополнительно выдаст ошибку, но только если отображения ошибок было отключено. Чудесно, не так ли?

В основном это означало, что на вашем dev-компьютере, вы не увидите никаких ошибок, но на production среде журнал ошибок будет заполнен вместе с ними. Удивительно.

В PHP 5.4 к счастью, такое поведение уже история. Ошибки больше не будут генерироваться.

Кроме того есть две опции, которые позволяют указать альтернативу возвращаемой пустой строке:

  • ENT_IGNORE: Этот вариант (который на самом деле не новый, он был и в PHP 5.3) просто отбросит всю некорректную последовательность кода. Это плохо по двум причинам: во-первых, вы не увидите недопустимых символов. Во-вторых, это накладывает определенный риск безопасности.
  • ENT_SUBSTITUTE: Это новая альтернативная опция. Вместо того чтобы просто удалять символы, они будут заменены на символ замены Юникод � (U + FFFD).

Давайте посмотрим на различные поведения (демо):

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

Обработка Doctype

В PHP 5.4 есть четыре дополнительных флага для указания doctype который нужно использовать:

  • ENT_HTML401 (HTML 4.01) => используется по умолчанию
  • ENT_HTML5 (HTML 5)
  • ENT_XML1 (XML 1)
  • ENT_XHTML (XHTML)


В зависимости какой doctype вы укажите htmlspecialchars (и другие родственные функции) будут использовать разные таблицы сущностей.

Таким образом, для HTML 5 сущность ‘ будет возвращена, а для HTML 4.01 — потому что он не поддерживает ‘ — числовой код ‘.
Разница становится более очевидной при использовании htmlentities, потому что там различий больше.
Вы можете легко убедиться в этом, когда посмотрите на сырые таблицы перевода.

Чтобы сделать это, можно использовать get_html_translation_table функцию. Вот пример для XML 1 doctype (демо):

Это соответствует нашим ожиданиям: XML сам по себе определяет только пять основных сущностей.
А теперь попробуем то же самое для HTML 5 (демо), и мы увидим нечто вроде этого:

HTML 5 определяет большое количество сущностей — 1510, если быть точным. Вы также можете попробовать указать HTML 4.01 и XHTML, они оба определяют 253 сущности.

Также затронутым от выбранного типа документа является еще одний новый флаг обработки ошибок, который я не упомянул выше: ENT_DISALLOWED. Этот флаг будет заменять символы на Unicode символы замены, которые формально являются корректными последовательностями кода, но недопустимы в данном DOCTYPE.

Таким образом, вы можете гарантировать, что возвращаемая строка будет всегда хорошо сформирована в отношении кодирования (в данном типе документа). Хотя я не уверен, много ли дает использование этого флага. Браузер обрабатывает недействительные символы изящно любом случае, так что это мне кажется ненужным (хотя я наверное не прав).

Это еще не все

… но я не хочу перечислять здесь все. Думаю, что три изменения, упомянутые выше, наиболее важные из улучшений.

Читают сейчас

Похожие публикации

  • 18 октября 2020 в 17:41

Небезопасные функции PHP

Открытый список PHP-событий, спикеров и организаторов на GitHub

Опрос. Новый тег для HTML-экранирования данных в PHP

Вакансии

AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Комментарии 30

> когда нибудь utf-8 станет классикой

Классикой в смысле «вымрет за ненадобностью»? ;)

Потому что вместо iconv на смену придет нормализованные и ненормализованные формы, каноникализация и т.д. и т.п., что ни один из языков (кроме, вроде, Perl’а) не поддерживает в полном объеме (если только нет полноценной привязки к ICU)

> Надеюсь, когда нибудь utf-8 станет классикой

Всем нам ещё очень много кода придется перебрать и конвертировать в utf-8.

> Как вы знаете, третий аргумент для htmlspecialchars это кодировка. Большинство людей просто упускают этот аргумент, таким образом, получая кодировку по умолчанию. Это значение было ISO-8859-1 до PHP 5.4. Новая версия исправляет это, сделав UTF-8 по умолчанию.

На сайтах с win1251 (я знаю, такие до сих пор есть) символы кириллицы будут поняты как неправильный UTF код и функция видимо будет возвращать пустую строку.

Я лично считаю, что дефолтная кодировка ISO это как раз хорошо, так как с ней функция только меняет 5 символов на сущности, а теперь она будет еще анализировать правильность UTF символов, и работать намного медленнее (и я не представляю ситуации где эта проверка нужна).

И еще, хотелось бы сказать всем, кто кричит о поддержке кодировок — идите на свой Питон, Яву или что у вас там есть. PHP всегда работал с бинарными строками, и работал замечательно, и никакой дополнительной поддержки НЕ требется. Все виду русских и нерусских букв давно поддерживаются. Бинарные строки без кодировок работают быстрее. Используйте utf-8 и mb_* функции для строк, флаг u для регулярок с русскими буквами, и никаких проблем (кроме ф-й из раздела preg-*) у вас никогда не будет. Если же вы настолько тупые, что этого не понимаете, то вам никакая встроенная поддержка юникода уже не поможет. Спасибо.

Жду не дождусь пхп-пример, где производительность упирается в скорость работы utf-8 строк :)
Более того, utf-8 и бинарные строки полностью идентичны в случае, когда не содержат символов кроме латиницы и пунктуации (ну, грубо, печатный ascii). А если содержат, то utf использовать все равно необходимо.

Все проблемы с 1251, как я понимаю, лечатся с помощью default_charset = блабла в php.ini

Нативная поддержка utf нужна везде, сейчас даже url-ы содержат кириллицу и иероглифы. parse_url() уже небезопасно использовать (баг #52923).

Недавно в аналогичной дискуссии по поводу PHP + UTF-8 кто-то кинул ссылку на интересную статью: www.amiro.ru/blog/tech/how-was-php6-died

Пишут, что при попытке внедрить UTF-8 везде и всюду на уровне ядра PHP, разработчики столкнулись с непреодолимыми тормозами, что забили на это дело.


Не UTF-8, а UTF-16. По той статье неясно насколько бы спасла ситуацию UTF-8, но как-то складывается впечатление, что спсла бы: Выбор был остановлен на UTF-16. Основным минусами этой кодировки являлось . множественные сопутствующие преобразования данных . Как позднее признаются разработчики, если бы они могли начать все сначала, то выбор бы пал на UTF-8.
Как следствие множественных преобразований данных, появилось ощутимое снижение производительности в работе критичных компонент PHP:

Но это же не «дублирующийся функционал», а совершенно разные вещи — байтовая строка и символьная строка.
Два набора функций — это хоть и зло, но едва ли не наименьшее из возможных.

Исторически получилось, что в php были только байтовые строки, и нельзя делать вид, что их больше нет, потому что это моментально ломает любой существующий код, работающий с бинарными файлами или сетевыми протоколами, да и вообще с любыми данными не в utf-8.
Поэтому нельзя просто так взять и «перейти на юникод» одним волшебным патчем — поди разбери, где в старом коде вызов какого-нибудь substr() должен на самом деле работать с байтами, а где с символами.
По этой же причине всякие mbstring.func_overload являются мертворожденными костылями.

По-хорошему, htmlspecialchars и многим другим (не всем) строковым функциям должно быть плевать, latin1 у них на входе или utf-8, пока заменяемые и заменяющие байты укладываются в диапазон 0-127, т.е., совпадают с символами.
Собственно, в этом и есть одно из ключевых преимуществ utf-8 — код, который ничего знает про различие между байтами и символами, в большинстве случаев просто работает (пока не лезет менять старшие байты).

Итого:
проблема есть, простого решения она не имеет, выбранное решение, к сожалению, больше создает новых проблем, чем решает старых.
Потом все будут жаловаться, а что это хостинги не спешат переходить на новую версию — ну а какому хостеру в здравом уме надо, чтобы при апгрейде у него сломались абсолютно все сайты, использующие кодировку, отличную от utf-8.

Э… а можно вопрос в кучу?

Есть ли какая альтернатива совершенно идиотскому использованию htmlspecialchars для проверки строки в UTF-8 на валидность? Друпальщики используют эту функцию в check_plain, что время от времени приводит к ошибкам, поскольку htmlspecialchars меняет строку, а это не всегда нужно.

htmlspecialchars()

Синтаксис:

htmlspecialchars(string[, flags[, charset[, double_encode]]])

Поддерживается следующими версиями PHP:

Описание функции:

Функция htmlentities() преобразует символы &,»»,», в HTML сущности. Возвращает преобразованную строку.

Обязательный аргумент. Строка которая будет отконвертировона

Необязательный аргумент. Флаг определяет как будут обрабатываться двойные и одинарные кавычки.

ENT_COMPAT — конвертируются двойные кавычки, а одинарные остаются без изменений (используется по умолчанию);

ENT_QUOTES — конвертируются двойные и одинарные кавычки;

ENT_NOQUOTES — любые кавычки не конвертируются;

ENT_IGNORE — если есть неверный код, то он отбрасавется. Без этого флага возвращается пустая строка (добавлено в версии 5.3). Этот флаг добавлен для обратной совместимости. Избегайте его использование, так как это может повлиять на безопасность.

Необязательный аргумент. Определяет кодировку, используемую при преобразовании. Поддерживаются следующие кодировки:

ISO-8859-1, ISO-8859-15, UTF-8, cp866, cp1251, cp1252, KOI8-R, BIG5, GB2312, BIG5-HKSCS, Shift_JIS, EUC-JP

Если ни одна из выше перечисленных кодировок не поддерживаются, то по умолчанию применяется ISO-8859-1

string double_encode Необязательный аргумент. Если double_encode отключен, то преобразования html-етгов не происходит. По умолчанию преобразуется всё. bool

Производятся следующие преобразования:

Примеры:

Пример 1:

$a = «Руководство по PHP»;
echo «Строка без обработки : «.$a;
echo «
«;
htmlspecialchars(«Руководство по PHP», ENT_QUOTES);
echo «Строка с обработкой: «.htmlspecialchars($a);
?>

Строка без обработки : Руководство по PHP
Строка с обработкой: Руководство по PHP

Код HTML страницы будет выглядеть следующим образом:

Строка без обработки : Руководство по PHP
Строка с обработкой: Руководство по PHP

htmlspecialchars онлайн

Функция в PHP, преобразующая специальные символы в html сущности. Такая обработка требуется перед вставкой текста в html-страницу.
Преобразуются символы & (амперсанд), « (двойная кавычка), (одинарная кавычка), (больше) следующим образом:
& => & | « => « | => | => >

Кириллица и htmlentities/htmlspecialchars. Проблема с русскими символами

Иногда по невнимательности возникает такая проблема, что функция htmlentities конвертирует кириллические буквы в нечитаемую последовательность символов. Это значит, что Вы не указали кодировку, которую функция будет использовать при преобразовании строки в html-сущности.

Решается эта проблема очень легко — необходимо добавить в вызов функции третий параметр-кодировку. Чаще всего это строка ‘UTF-8’ или ‘cp1251’. Также Вы можете использовать функцию htmlspecialchars вместо htmlentities. Она работает таким же образом, но конвертирует меньший диапазон специальных символов. Не забывайте про кодировку, в htmlspecialchars также есть этот аргумент.

Приведем небольшой пример, при котором htmlentities/htmlspecialchars возвращают кракозябли вместо строки с кириллическими символами:

В результате на странице видим Ð�иÑ�иллиÑ�а вместо слова «Кириллица». После добавления двух параметров ENT_QUOTES и ‘UTF-8’, проблема исчезает:

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL