web-dev-qa-db-ja.com

WordPressはpost_metaのJSON文字列からエスケープバックスラッシュを削除しています

カスタムのpost_metaフィールドに一部のコンテンツをJSONとして保存することで、自分の人生を楽にし、未来を意識していると思いました。残念ながら、WordPressは同意せず、私の人生を非常に難しくしています。

基本的にこのようなJSON文字列があります。これはほんの1ビットで、コメント文字列は単なるダミーの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_UNESCAPED_UNICODEフラグはPHP 5.3.xインストールであるため使用できません。また、コンテンツがjson_encodeに渡される前にhtmlentitiesでエンコードを試みましたが、 UTF-8エンティティの小さなサブセットのみをキャプチャします。

前もって感謝します!

(編集:FWIW、配列を直接post_metaに保存することができ、シリアル化されて魔法が発生することがわかっていますが、データをJSONとして保存するというアイデアが好きです。簡単でエレガントなソリューションがない場合私は洞窟に行きますが、私はそこに非常に期待しています簡単でエレガントなソリューションです!)

8

それを回避する方法があるようには見えません。

最終的にメタを保存する責任があるupdate_metadata()関数は、メタ値に対して明示的にstriplashes_deep()を実行します。値が配列の場合、この関数は配列要素からスラッシュを削除します。

それはsanitize_metaと呼ばれるAFTERの後に実行されるフィルタです。しかし、その時点では、スラッシュは既に取り除かれているので、それらをどこに追加する必要があるのか​​を確実に判断することはできません値の)。

それがなぜこれをするのかについて話すことができませんが、それはします。おそらく、それはwpdb-> updateを経て実行されるため、文字列をエスケープ解除する必要があります。

あなたが恐れていたように、あなたはおそらくあなたが言ったように直列化されるでしょう、単に配列として値を格納するほうが得策です。後でJSONとして使用したい場合は、json_encode()を使用して実行できます。

6
MathSmath

これを処理するためのエレガントな方法があります。

JSONエンコードされた文字列を wp_slash() に渡します。この関数は、エンコードされた各Unicode文字の先頭のスラッシュをエスケープします。これにより、update_metadata()がそれらを削除するのを防ぎます。

19
jkereako

あなたはこのような何かでワードプレスに詐欺することができます:

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

このthat 簡単 * エレガントな解 * ...

4
drmartin

この関数は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、16進数)シーケンスの前にバックスラッシュを追加します。 DBに送信する前に、この関数を呼び出してください。

2
Florin Chis

まだ wp_update_post を介してjsonでエンコードされたUnicode文字列を保存するのに苦労している人のために、以下は私のために働きました。 の中に見つかりました - 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 ) );
1
gbones

これを回避する興味深い方法は、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
David Allen

あなたはWordPress striplashes_deep()関数を使うことができます。

<?php stripslashes_deep($your_json);?>

参照のために ここ

0
Irfan Bin Hakim