开发者必藏:WordPress 数据转义是怎么处理的?
要了解 WordPress 数据转义是怎么处理的,首先要从 PHP 的古老特性的魔术引号(Magic Quotes)开始说起,尽管该特性自 PHP 5.3.0 起被废弃,并自 PHP 5.4.0 起被移除。
PHP 的魔术引号特性(Magic Quotes)
魔术引号是一个自动将数据进行转义的过程,当魔术引号打开时,所有的 '
(单引号),"
(双引号),\
(反斜线)和 NULL
字符都会被自动加上一个反斜线进行转义,和 PHP 原生函数 addslashes()
作用完全相同。
魔术引号存在的问题
魔术引号是为了阻止 SQL 注入,这样可以帮助新手在不知不觉中写出了更好(更安全)的代码,但是:
- 魔术引号打开或关闭都会影响到可移植性。
- 由于并不是每一段被转义的数据都要插入数据库的,如果所有数据都被转义的话,那么会对程序的执行效率产生一定的影响。
- 由于不是所有数据都需要转义,在不需要转义的地方看到转义的数据就很烦。
由于上述的原因,所以 PHP 的魔术引号特性已自 PHP 5.3.0 起被废弃,并自 PHP 5.4.0 起被移除。
WordPress 是如何进行数据转义的?
既然该特性已经被移除,我们为什么要啰里啰嗦介绍半天呢?那是因为 WordPress 是一个生命力很强的程序,他在 PHP 很早期代码的时候就存在了。
在早期的时候,为了考虑程序移植性,不管环境是否开启了魔术引号,WordPress 都强制将 $_GET
、$_POST
、$_COOKIE
和 $_SERVER
中的字符串的 '
(单引号),"
(双引号),\
(反斜线)和 NULL
字符都自动加上一个反斜线进行转义,相当于不管环境设置,WordPress 都开启魔术引号:
function wp_magic_quotes() {
// 使用 wpdb 进行转义
$_GET = add_magic_quotes( $_GET );
$_POST = add_magic_quotes( $_POST );
$_COOKIE = add_magic_quotes( $_COOKIE );
$_SERVER = add_magic_quotes( $_SERVER );
// Force REQUEST to be GET + POST.
$_REQUEST = array_merge( $_GET, $_POST );
}
所以尽管 PHP 5.4 之后,魔术引号特性已经被移除,但是为了保持代码的一致性和兼容性,WordPress 这个操作一直保留下来,并且会一直保留下去,所以:
WordPress 的 $_GET
、$_POST
、$_COOKIE
、$_SERVER
和 $_REQUEST
数据中的字符串是被转义的。
这个是 WordPress 和其他 PHP 框架最大的不同,所以在 WordPress 进行开发的时候,一定要记住这个,不然会引起一些莫名其妙的问题,然后根本不知道怎么去解决。
WordPress 转义和反转义函数
在深入开发者必备要点之前,我们先了解 WordPress 提供的转义和反转义函数。
首先 PHP 提供了函数 addslashes()
可以对字符串进行转义,然后通过函数 stripslashes()
对已经转义的函数进行反转义。
上面两个函数只能对字符串操作,如果对数组中的字符串进行操作,就只能进行 for 循环,然后对每一项进行操作。
为了方便操作,WordPress 提供了两个常用的函数除了对字符串进行转义和反转义操作之外,也可以对数组中的字符串进行转义和反转义操作,
- wp_slash($value):以递归方式将反斜杠添加到字符串或字符串数组中
- wp_unslash($value):删除字符串或字符串数组中的反斜杠。
WordPress 开发者应该怎么处理呢
我总结了一下,关于 WordPress 转义有以下几个要点要记一下,我每次碰到问题的时候,都会打开这篇文章回顾下面这几个要点,很多问题,都会迎刃而解。😆
- 首先要记住: WordPress 的
$_GET
、$_POST
、$_COOKIE
、$_SERVER
和$_REQUEST
数据中的字符串是被转义的。 - 数据插入数据库之前,如果数据已经被转义,要进行反转义操作,因为 WordPress 的数据库操作类有自己的转义函数
wpdb::prepare()
。 - 使用 WPJAM Basic 的
wpjam_get_parameter()
函数获取的数据是已经反转义了的。 - 文章,分类,评论和用户等的新增和修改函数,以及它们 meta 的新增和修改函数,这些 WordPress 原生函数内部都是有进行反转义操作的(使用 wp_unslash() 函数),所以不要双重反转义了。
- 如果数据已经反转义或者未转义,使用这些 WordPress 原生函数之前,反而要对数据进行转义操作(使用 wp_slash() 函数)。
- 注意例外情况:选项的新增(
add_optioon()
)和修改(update_option()
)函数内部是没有进行进行反转义操作,所以如果有需要的话,开发者要自己进行反转义操作,一般不需要。 - 进行反向操作的时候,一定要注意顺序,比如数据先序列化,然后转义,反向操作的时候,一定要先反转义,再反序列化,如果先反序列化,再反转义,则可能会反序列化出错。
- 为了减少出错的概率,进行序列化操作时,一般要求要传递未转义的数据,如果已经转义,要使用 wp_unslash() 反转义回来。