规则1 {#why}
当我们谈论转义时,通常是关于我们从数据库中获得的信息。但是请记住,该数据库不是受信任的数据源。让我给你看一个例子:
echo '<label for="' . $id . '">' . $label . '</label>'; ...
我们在HTML属性中有一个变量,而在HTML标签中有另一个。假设它$label
来自数据库,并且包含以下内容:
'<script>window.location = "https://not-www.wpon.cn";</script>'
无需以表格形式显示标签,您的网站用户将被重定向到一些阴暗的网站。看起来不错?不。
同样的事情也适用于$id
HTML属性中的变量。这是这样的:
'"><script>window.location = "https://not-www.wpon.cn.com";</script>'
重定向对于您来说似乎并不那么麻烦,但是如果有某种比特币挖掘脚本怎么办?
治愈
为了防止在上面的示例中发生这种废话,我们要做的就是将输出包装在其中esc_attr()
并esc_html()
相应地包装。方法如下:
echo '<label for="' . esc_attr( $id ) . '">' . esc_html( $label ) . '</label>'; ...
太好了,现在您已经了解了基础知识,让我们继续
什么时候? {#when}
这是一个非常好的问题,因为据说在WordPress的官方文档中,某些WordPress函数负责准备数据以供输出,并举例说明了这些the_title()
函数。
让我们现在检查一下!我什至没有说过要更改phpMyAdmin中的标题,这当然也是可能的,所以让我们创建一个标题如下的帖子:
在使用the_title()
或打印标题的网站页面上get_the_title()
,我们得到了:
但请注意,尽管它使用相同的get_the_title()
功能来打印标题,但/ wp-admin中的WP_Posts_List_Table并未损坏。
标题在这里两次被转义了。
这是什么意思?!
在WordPress管理页面中,函数是get_the_title()
通过esc_html()
以下方式进行转义的:
add_filter( 'the_title', 'esc_html' );
WordPress在真正重要的地方逃避了一切,同时当我们谈论网站前端时,它为用户提供了自由。
这就是我的想法--您可以选择在创建自定义主题的模板时决定是否转义标题等,但是如果您正在开发插件或WordPress管理员的某种UI,则转义是永远是必须的。
esc_attr()
从函数名称可以理解,它为HTML属性中的用法准备了数据。
删除不正确的utf8,
将< (小于),> (大于),& (与号)," (双引号)和'(单引号)字符转换为HTML实体,
永远不会对实体进行双重编码。
例:
echo '<a href="" title="View post: ' . esc_attr( get_the_title() ) . '">...';
请记住:
- 不要使用
esc_attr()
来转义src
,href
属性的数据-- 而是使用esc_url(), value
也不要将其用于属性,因为它可能导致HTML实体丢失和数据库中存储的值不正确,请改用esc_textarea()。这是因为esc_attr()
不会对实体进行双重编码。
esc_html() {#esc_html}
准备在HTML中使用的文本。与esc_attr()函数的唯一区别在于,它有一个连接到函数输出的过滤器钩子- esc_html
而不是attribute_escape
。
示例--假设您有一个类似的字符串,<div class="block">
并且想要在网站内容中显示它。
$string = '<div class="block">';
echo esc_html( $string ); // outputs <div class="block">
esc_url()
检查,尝试修复和清除URL。这是相同的顺序:
- 用替换空格
%20
, - 删除网址中不允许使用的符号,例如反斜杠,
- 如果URL协议是
mailto:
,排除符号%0d
,%0a
,%0D
,%0A
从使用私有字符串_deep_replace()
这意味着字符串等功能%0%0%0AAA
将被转换为空字符串,而不是%0%0AA
其str_replace()
将返回, - 替换
;//
为://
万一发生错误的情况, - 如果URL中不包含的方案,
http://
将预置除非它是先从相对链接/
,#
或者?
或php
文件)。 - 如果第三个函数参数
$_context
等于display(默认情况下),则&符号将替换为,&
并将单引号替换为'
, - 用
%5B
和编码方括号%5D
。 - 检查是否允许使用URL协议,如果不允许-返回空字符串,
- 最后,将
clean_url
滤镜挂钩应用于结果。
echo '<a href="' . esc_url( $url ) . '">...</a>';
允许的协议
默认情况下,WordPress列出了可以使用函数检索的良好协议wp_allowed_protocols()
,这是列表
- http / https
- FTP / FTPS
- 邮寄
- 新闻
- irc
- 地鼠
- 恩特普
- 饲料
- 远程登录
- 彩信
- 短信
- rtsp
- svn
- 电话
- 传真
- xmpp
- Webcal
- 瓮
如上所述,如果您的网址既不是相对网址,也不包含任何这些协议,则将返回空字符串。但是,如果您想逃避这样的Skype链接skype:rudrastyh?call
怎么办?
您可以使用此过滤器挂钩将" skype"添加到允许的协议列表中kses_allowed_protocols
。例:
add_filter( 'kses_allowed_protocols', function( $protocols ) {
$protocols[] = 'skype';
return $protocols;
});
另一种方法是在转义时直接指定协议:
$url = 'skype:rudrastyh?call';
echo '<a href="' . esc_url( $url, array( 'skype' ) ) . '">Call Misha</a>';
esc_js()
转义字符串以用作内联JavaScript,例如onclick=""
,onsubmit=""
或在<script>
标记内。请注意,在这种情况下,JavaScript中的文本字符串必须始终用单引号引起来!
- 删除不正确的utf8,
- 转义单引号
'
, - 将
<
(少于),>
(大于),&
(与号),"
(双引号)字符转换为HTML实体< > & "
, \n
在行末添加。
您现在看到了esc_js()
和esc_attr()之间的区别吗?
让我们看一个例子:
<?php
$text = "some single ' quote
then the next line and <b>html code</b>";
?>
<script>
alert('<?php echo esc_js($text) ?>');
</script>
如果您不打算esc_js()
在此示例中使用,将出现JavaScript错误并且没有发生任何事情,但是在我们的情况下,我们在浏览器中收到如下警告消息:
esc_textarea() {#esc_textarea}
为<textarea>
标签内的用法准备一个字符串。
- 将
<
(小于),>
(大于),&
(与号),"
(双引号)和'
(单引号)字符转换为HTML实体,
与本地化逃离 {#escaping_with_localization}
还值得一提的一对夫妇像定位功能esc_html__()
,esc_html_e()
,esc_html_x()
,esc_attr__()
,esc_attr_e()
,esc_attr_x()
这不仅是翻译字符串,但也难逃他们。
例:
esc_html_e ( 'Hello World','some_text_domain' ) ;
//绝对相同的
echo esc_html ( __ ( 'Hello World','some_text_domain' ) ) ;