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


11

我以为可以通过将一些内容另存为JSON位以保存在自定义post_meta字段中,从而使自己的生活变得轻松,并着眼于未来。不幸的是,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_decode转换为有用的内容了。

关于WordPress为什么会这样做的任何想法,以及是否有避免的方法?我不能使用JSON_UNESCAPED_UNICODE标志,因为这是PHP 5.3.x安装,并且htmlentities在内容传递给之前我已经尝试使用进行编码json_encode,但这仅捕获了UTF-8实体的一小部分。

提前致谢!

(编辑:FWIW,我知道我可以将一个数组直接保存到post_meta中,它将被序列化,并且会发生魔术,但是我只是喜欢将数据存储为JSON的想法。如果没有一种简单,优雅的解决方案我会的洞穴,但我非常希望有一个简单的,优雅的解决方案!)

Answers:


8

看起来没有任何方法可以避免这种情况。

最终负责保存元数据的update_metadata()函数在元值上显式运行stripslashes_deep()。如果值是数组,则此函数甚至会删除数组元素中的斜线。

在之后运行的过滤器名为sanitize_meta,您可以将其连接到其中。但是到那时,您的斜杠已经被去除,因此您无法可靠地确定需要将它们添加回何处(或者至少,我不知道如何区分引用合法JSON分隔符与位之间的区别值)。

不能说为什么这样做,但确实如此。可能是因为它最终要通过wpdb-> update运行,这需要对字符串进行转义。

正如您所担心的,最好将值存储为数组,然后将其序列化(如您所说),这样可能会更好。如果以后要使用JSON,则可以通过json_encode()运行它。


我对此感到害怕,但是很高兴知道为什么会这样。非常感谢您的快速回复!
克里斯·范·帕滕

这也不是事实,请参见其他答案:)
jave.web

@ jave.web的确,您无法避免在字符串上使用update_metadata()运行带斜线。其他答案提供了(非常聪明的)解决方法,可以从根本上“双倍转义”您的字符串,以便不可避免的剥离会除去那些多余的斜杠,但会使您的原始斜杠完好无损。我个人还是要说,“优雅”的处理方式是将数据存储在数组中,而无需任何特殊的处理或预格式化。然后在需要时将其转换为json。但这只是我的偏爱。
MathSmath,2015年

25

有一种优雅的方式可以解决这个问题!

通过传递JSON编码的字符串wp_slash()。该函数将转义每个编码的unicode字符的前导斜线,从而防止update_metadata()剥离它们。


这是严重的Wordpress错误的解决方法。非常感谢!
netAction

2
这应该是公认的答案。我遇到了通过wp_insert_post从GitHub导入内容的问题,这是从代码示例中删除斜杠的主要问题。在通过wp_insert_post发送字符串之前,先通过wp_slash运行字符串就可以了。谢谢!
Matt Keys)

即使在今天,这仍然很有用,我花了很多小时才找到解决方法,而没有一个线索,直到我找到了。如果您想在以下问题上添加此答复:stackoverflow.com/questions/61091853/…我将其标记为正确答案。非常感谢!
Jaypee

4

您可以使用以下内容欺骗Wordpress:

$cleandata = str_replace('\\', '\\\\', json_encode($customfield_data, true));

就是这么简单 * 优雅的解决方案 * ...


+1这可以解决我的问题。它与OP稍有不同,但相似。
亚当·斯普里格斯

2

此函数使用preg_replace进行转换:

function preg_replace_add_slash_json($value) {
    return preg_replace('/(u[0-9a-fA-F]{4})/i', '\\\$1', $value);
}

在每个“ uXXXX”(X = 0..F,十六进制)序列之前,它添加反斜杠。提交给数据库之前,请调用此函数。


1

解决这个问题的一种有趣方法是编码为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 ))

1

对于仍在努力通过wp_update_post保存json编码的unicode字符串的任何人,以下对我有用。在class-wp-rest-posts-controller.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 ) );

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.