esc_attr() — подготавливает строку для использования в HTML-атрибуте

Владислав Белецкий
Владислав Белецкий .
Категория:
Комментариев: 0

Если вы откроете исходный код ядра WordPress или какого-нибудь плагина, то скорее всего вы заметите, что значения атрибутов перед выводом пропускаются через функцию esc_attr().

Что конкретно делает функция: преобразует символы < > & " ' в HTML-сущности, а именно в
< > & " ' соответственно. Повторное преобразование не производится.

Также есть похожие функции – esc_attr__() и esc_attr_e() – они нужны при работе с локализацией.

esc_attr( $text )

Параметры

$text
(строка) Текст, который планируется использоваться в качестве значения HTML-атрибута.

Примеры

1. Результат действия функции

$text = "<span>(тег) '(кавычка) "(двойная кавычка) &(амперсанд)";
echo esc_attr( $text );
 
// Будет выведено
// <span>(тег) '(кавычка) "(двойная кавычка) &(амперсанд)

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

2. Спасаемся от взломанной базы данных

Чуть выше я упоминал пример с изображением и атрибутом alt. Пришло время разобрать его по шагам, почему бы и нет.

$alt = // получили из базы данных что-то
echo '<img src="" alt="' . $alt . '" />';

Так вот, что если в базу данных каким-то образом загнали JavaScript-код майнинга (предположим), и мы получаем оттуда значения для alt равное "><script>код майнинга</script>

Тогда, когда оно подставится в alt атрибут, мы получим, что атрибут alt закроется, тег <img> закроется, и начнёт выполняться тег <script>. А после ещё выведется обычным текстом />.

<img src="" alt=""><script>код майнинга</script> />

Однако, если мы защитим атрибут функцией esc_attr(), вот так:

$alt = // получили из базы данных что-то
echo '<img src="" alt="' . esc_attr( $alt ) . '" />';

Тогда весь вредоносный код будет проэкранирован и он никак не выполнится, лишь выведется внутри атрибута alt.

<img src="" alt=""><script>код майнинга</script>" />

3. Двойное экранирование

Выше я упоминал, что если у вас в строке уже есть HTML-сущности, то повторному экранированию они подвергнуты не будут, то есть < не превратится в &lt;.

Окей, а что делать, если вам это нужно сделать? Тут нас может выручить PHP-функция htmlspecialchars().

$text = "<span>";
echo esc_attr( $text );         // <span>
echo htmlspecialchars( $text ); // &lt;span&gt;

4. Использование в формах

В интернете можно встретить пример по использованию функции esc_attr() внутри атрибута value в поле формы. Он примерно такой:

$fname = ( isset( $_POST['fname'] ) ) ? $_POST['fname'] : '';
echo '<input type="text" name="fname" value="' . esc_attr( $fname ) . '">';

Но к этому примеру важно добавить некоторые пояснения, и я сейчас их и добавлю.

Итак, при использовании функции для очистки атрибута value в формах, вы будете терять HTML-сущности!

Предположим, что у нас есть какой-то текст в базе данных, содержащий экранированный HTML-тег и обычные двойные кавычки, например Используйте тег "br" (<br>). А также у нас есть обычное текстовое поле, значение которого очищается функцией esc_attr().

echo '<input type="text" value="' . esc_attr( $value ) . '">';

Подставим в value значение из базы данных?

Но (!) браузер обрабатывает HTML-сущности внутри полей формы и пользователю отобразится: Используйте тег "br" (<br>), и поля в принципе так работают, что и значение поля станет таким же. А значит, при отправке формы и сохранении её в базу данных мы теряем все HTML-сущности в строке и значение в базе данных становится Используйте тег "br" (<br>).

В таком случае ситуацию поможет спасти использование esc_textarea(), которая осуществляет повторные преобразования.

esc_attr: <input value="Используйте тег &quot;br&quot; (&lt;br&gt;)">
esc_textarea: <input value="Используйте тег &quot;br&quot; (&amp;lt;br&amp;gt;)">

Хуки

attribute_escape

К возвращаемую результату функции esc_attr() дополнительно применяется фильтр-хук attribute_escape, который позволяет модифицировать очищенное значение.

return apply_filters( 'attribute_escape', $safe_text, $text );
$safe_text
(строка) Очищенный функцией текст.
$text
Оригинальный текст, переданный в функцию.

В дополнении предыдущего примера, покажу вам, как при помощи этого фильтра не очищать одну определённую строку.

add_filter( 'attribute_escape', 'true_skip_escaping_specific_string', 25, 2 );
 
function true_skip_escaping_specific_string( $safe_text, $text ) {
 
	if( 'Используйте тег "br" (<br>)' === $text ) {
		return $text;
	}
	return $safe_text;
 
}

Не знаете, как работать с фильтрами? Смотрите этот урок.

Подписаться
Уведомить о
guest
0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии