PHP+WordPress中wp_unslash作用解析及字符串转义问题
问题描述
我是自学的初级程序员,一直没完全搞懂字符串的正确处理方法。比如把"Cos'ì è l'amore"写入数据库时,会被存成"Cos\'ì è l\'amore",我猜和字符串编码有关,但找不到清楚的解释。
我的场景是:通过AJAX发请求(创建JavaScript对象后以数组形式发给服务器),用WordPress的$wpdb->update方法更新数据库。数据库列用的是WordPress标准的utf8mb4_general_ci编码,数据是从UTF-8格式的CSV导入的。
AJAX请求代码
$.ajax({ method:'POST', url:bmajax_obj.ajax_url, data:{ 'action':'modify', '_ajax_nonce': bmajax_obj.nonce, 'id':$form.attr('data-bm-id'), 'data':dataObj }, success : function(){ $('form[id="form-modal-editing"]').attr('data-bm-changed',false); $('#modal-btn-save').attr('disabled',true); $('#modal-editing').modal('hide'); }, error : function(error){ console.log(error); } });
后端处理代码
modify_handler函数
function modify_handler() { check_ajax_referer( 'admin' ); if (isset($_POST['id']) && !empty($_POST['id']) && isset($_POST['data']) && !empty($_POST['data'])){ $id = wp_unslash( $_POST['id']); $data = $_POST['data']; $v = self::$BM_Query->set_post($id,$data); if($v) echo "Successfull"; else echo "Failed"; } wp_die(); }
set_post方法
public function set_post($id,$data){ global $wpdb; $keys = array( 'num_ing', 'num_coll', 'title', 'author', 'catalog', 'year' ); $metakeys = array('editor','category','section','tags', 'extract', 'rif_ing', 'rif_coll'); $dataObj = array(); $meta = array(); if( is_array($id) || empty(($id)) ) return false; if(!is_array($data)) return false; foreach ($data as $key => $value) { if(!in_array($key,$keys) && in_array($key,$metakeys)) $meta[$key] = $value; else $dataObj[$key] = $value; } $dataObj['meta'] = json_encode($meta); if(is_numeric($id)){ $wpdb->update($this->tablename,$dataObj,array('id'=>$id)); return $dataObj['meta']; } }
我最后发现解决方案是在modify_handler函数里给$data也加上wp_unslash处理。作为新手,我想知道为什么必须用wp_unslash处理字符串?
解答
核心原因:避免双重转义
这和WordPress的全局变量转义机制直接相关:
- 为了兼容老版本PHP的魔术引号特性(该特性会自动给POST/GET/COOKIE中的特殊字符加反斜杠转义),WordPress会自动给
$_POST、$_GET、$_COOKIE这类全局变量里的所有字符串添加反斜杠。 - 而WordPress的
$wpdb类(包括update、insert等方法)本身已经内置了安全的转义逻辑(基于wpdb::prepare),会自动对要存入数据库的内容做转义处理。
如果不对$_POST['data']调用wp_unslash,就会出现双重转义:
- WordPress先给字符串里的单引号加了反斜杠(比如把
Cos'ì变成Cos\'ì); $wpdb->update再次对这个字符串转义,把反斜杠当成需要转义的字符,最终存入数据库的就是带多余反斜杠的内容。
为什么wp_unslash是正确选择
wp_unslash是WordPress官方推荐的处理方式,它能递归处理数组(你的$data是数组格式),自动去掉所有嵌套字符串中的多余反斜杠;- 不要用PHP原生的
stripslashes,它只能处理单个字符串,无法处理数组结构的$data。
你的场景对应
你一开始只给$id做了wp_unslash处理,但$data里的字符串还保留着WordPress自动添加的反斜杠。当$wpdb->update处理这些字符串时,就会触发双重转义,导致数据库里出现多余的反斜杠。给$data加上wp_unslash后,相当于先还原出原始字符串,再交给$wpdb做正确的转义,最终存入的就是正常的内容。
内容的提问来源于stack exchange,提问作者f3l1x
相关产品推荐
相关产品推荐

