WordPress正在从post_meta中的JSON字符串中去除转义反斜杠

时间:2012-05-25 作者:Chris Van Patten

我认为通过将一些内容保存为自定义post\\u元字段中的JSON片段,可以让我的生活变得轻松,并关注未来。不幸的是,WordPress不同意,这让我的生活变得异常艰难。

我有一个JSON字符串,本质上看起来像这样。这只是一位,注释字符串只是一些伪unicode实体。整件事都是通过/json_encode.

{
    "0": {
        "name": "Chris",
        "url": "testdomain.com",
        "comment": "\\u00a5 \\u00b7 \\u00a3 \\u00b7 \\u20ac \\u00b7 \\u00b7 \\u00a2 \\u00b7 \\u20a1 \\u00b7 \\u20a2 \\u00b7 \\u20a3 \\u00b7 \\u20a4 \\u00b7 \\u20a5 \\u00b7 \\u20a6 \\u00b7 \\u20a7 \\u00b7 \\u20a8 \\u00b7 \\u20a9 \\u00b7 \\u20aa \\u00b7 \\u20ab \\u00b7 \\u20ad \\u00b7 \\u20ae \\u00b7 \\u20af \\u00b7 \\u20b9"
    }
}
不幸的是,在我用update_post_meta, 结果是这样的:

{
    "0": {
        "name": "Chris",
        "url": "testdomain.com",
        "comment": "u00a5 u00b7 u00a3 u00b7 u20ac u00b7 u00b7 u00a2 u00b7 u20a1 u00b7 u20a2 u00b7 u20a3 u00b7 u20a4 u00b7 u20a5 u00b7 u20a6 u00b7 u20a7 u00b7 u20a8 u00b7 u20a9 u00b7 u20aa u00b7 u20ab u00b7 u20ad u00b7 u20ae u00b7 u20af u00b7 u20b9"
    }
}
去掉斜杠,就不可能了json_decoded返回到有用的内容中。

你知道WordPress为什么会这样做吗?有没有办法避免?我不能使用JSON\\u UNESCAPED\\u UNICODE标志,因为这是一个PHP 5.3。x安装,我已经尝试使用htmlentities 将内容传递给之前json_encode, 但这只捕获了UTF-8实体的一小部分。

提前感谢!

(编辑:FWIW,我知道我可以直接将一个数组保存到post\\u meta,然后将其序列化,这样会有奇迹发生,但我只是喜欢将数据存储为JSON的想法。如果没有简单、优雅的解决方案,我会放弃,但我非常希望有一个简单、优雅的解决方案!)

7 个回复
最合适的回答,由SO网友:MathSmath 整理而成

看来没办法避免了。

update\\u metadata()函数最终负责保存meta,它显式地对meta值运行stripslashes\\u deep()。如果值是数组,此函数甚至会从数组元素中删除斜杠。

在那之后运行一个名为sanitize\\u meta的过滤器,您可以连接到它。但此时,您的斜杠已经被剥离,因此您无法可靠地确定需要在何处重新添加斜杠(或者至少,我不知道您如何区分引用合法JSON分隔符与引用二进制值之间的区别)。

我说不出它为什么这样做,但它确实这样做了。可能是因为它最终是通过wpdb->update运行的,这需要不替换字符串。

正如您所担心的,您最好将值存储为一个数组,然后将其序列化(如您所说)。如果以后希望它成为JSON,可以通过JSON\\u encode()运行它。

SO网友:jkereako

有一种优雅的方式来处理这个问题!

传递JSON编码的字符串wp_slash(). 该函数将转义每个编码的unicode字符的前斜杠,这将阻止update_metadata() 从剥离它们。

SO网友:drmartin

你可以这样欺骗wordpress:

$cleandata = str_replace(\'\\\\\', \'\\\\\\\\\', json_encode($customfield_data, true));
这就是easy *优雅的解决方案*。。。

SO网友:Florin Chis

此函数使用preg\\u replace执行转换:

function preg_replace_add_slash_json($value) {
    return preg_replace(\'/(u[0-9a-fA-F]{4})/i\', \'\\\\\\$1\', $value);
}
在每个“uxxx”(X=0..F,十六进制)序列之前,它添加反斜杠。在提交到DB之前,调用此函数。

SO网友:gbones

对于那些仍在努力通过wp\\u update\\u post保存json编码的unicode字符串的人来说,以下内容对我很有用。在wp类rest posts控制器中找到。php

// convert the post object to an array, otherwise wp_update_post will expect non-escaped input.
wp_update_post( wp_slash( (array) $my_post ) ); 
下面是一个示例:

$objectToEncodeToJson = array(
  \'my_custom_key\' => \'<div>Here is HTML that will be converted to Unicode in the db.</div>\'
);

$postContent = json_encode($objectToEncodeToJson,JSON_HEX_TAG|JSON_HEX_QUOT);

$my_post = array(
  \'ID\'           => $yourPostId,
  \'post_content\' => $postContent
);

wp_update_post( wp_slash( (array) $my_post ) );

SO网友:David Allen

解决这个问题的一个有趣的方法是编码到base64,请参见下面的示例。

$data = Array(0 => array(\'name\' => \'chris\' , \'URL\' => "hello.com"));

$to_json = json_encode($data);

echo $to_json  . "<br />";
//echos [{"name":"chris","URL":"hello.com"}] 

$to_base64 =  base64_encode($to_json);

Echo $to_base64 . "<br />";
//echos W3sibmFtZSI6ImNocmlzIiwiVVJMIjoiaGVsbG8uY29tIn1d

$back_to_json =  base64_decode($to_base64);

Echo $back_to_json . "<br />";
//echos [{"name":"chris","URL":"hello.com"}]

$back_to_aray = json_decode($back_to_json);

print_r($back_to_aray) ;
//echos  Array ( [0] => stdClass Object ( [name] => chris [URL] => hello.com ))

SO网友:Irfan Bin Hakim

您可以使用WordPress stripslashes\\u deep()函数。

<?php stripslashes_deep($your_json);?>
参考访问here

结束