You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,就会出现双重转义:

  1. WordPress先给字符串里的单引号加了反斜杠(比如把Cos'ì变成Cos\'ì);
  2. $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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 23:42:38