Je pensais me simplifier la vie et être conscient de l'avenir en enregistrant du contenu sous forme de fragments de JSON dans des champs post_meta personnalisés. Malheureusement, WordPress n'est pas d'accord et me rend la vie incroyablement difficile.
J'ai une chaîne JSON qui ressemble essentiellement à ceci. Ceci est juste un bit, et la chaîne de commentaire est juste quelques entités fictives Unicode. Le tout est généré avec/ 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"
}
}
Malheureusement, après l'avoir sauvegardé avec update_post_meta
, le résultat est le suivant:
{
"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"
}
}
Et avec les barres obliques supprimées, il est impossible de redonner à json_decode
d un contenu utile.
Des idées sur la raison pour laquelle WordPress pourrait le faire et s’il existe un moyen de l’éviter? Je ne peux pas utiliser l'indicateur JSON_UNESCAPED_UNICODE car il s'agit d'une installation PHP 5.3.x et j'ai déjà essayé d'encoder avec htmlentities
avant que le contenu ne soit passé à json_encode
, mais cela ne capture qu'un petit sous-ensemble de fichiers UTF. -8 entités.
Merci d'avance!
(EDIT: FWIW, je sais que je pourrais sauvegarder un tableau directement dans post_meta. Il serait sérialisé et la magie opérerait, mais j'aime bien l'idée de stocker les données au format JSON. S'il n'y a pas de solution simple et élégante Je vais céder, mais j'espère beaucoup est une solution simple et élégante!)
On dirait qu'il n'y a aucun moyen de l'éviter.
La fonction update_metadata (), qui est responsable de la sauvegarde de la méta, exécute explicitement un stripslashes_deep () sur la méta-valeur. Cette fonction supprimera même les barres obliques des éléments du tableau, si la valeur était un tableau.
Il existe un filtre exécuté APRÈS appelé sanitize_meta, auquel vous pouvez vous connecter. Mais à ce stade, vos barres obliques ont déjà été supprimées. Vous ne pouvez donc pas déterminer de manière fiable où elles doivent être rajoutées (ou du moins, je ne sais pas comment vous feriez la différence entre citer des délimiteurs JSON légitimes et des bits des valeurs).
Je ne peux pas dire pourquoi il fait cela, mais ça le fait. Probablement parce qu'il est éventuellement exécuté via wpdb-> update, ce qui nécessite que les chaînes ne soient pas échappées.
Comme vous le craigniez, vous feriez probablement mieux de stocker la valeur sous forme de tableau, qui sera sérialisé (comme vous l'avez dit). Si vous le souhaitez en tant que JSON ultérieurement, vous pouvez simplement l'exécuter via json_encode ().
Il existe un moyen élégant de gérer cela!
Passez la chaîne encodée JSON par le biais de wp_slash()
. Cette fonction échappera à la barre oblique de chaque caractère unicode codé, ce qui empêchera update_metadata()
de les supprimer.
Vous pouvez tricher à wordpress avec quelque chose comme ça:
$cleandata = str_replace('\\', '\\\\', json_encode($customfield_data, true));
This est that easy * solution élégante * ...
Cette fonction effectue la transformation à l'aide de preg_replace:
function preg_replace_add_slash_json($value) {
return preg_replace('/(u[0-9a-fA-F]{4})/i', '\\\$1', $value);
}
Avant chaque séquence "uXXXX" (X = 0..F, hexadécimale), une barre oblique inverse est ajoutée. Avant de soumettre à la base de données, appelez cette fonction.
Pour ceux qui ont encore du mal à sauvegarder une chaîne unicode encodée JSON via wp_update_post , les éléments suivants ont fonctionné pour moi. Trouvé dans 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 ) );
Voici un exemple:
$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 ) );
Une solution intéressante consiste à encoder en base64, voir l'exemple ci-dessous.
$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 ))
Vous pouvez utiliser la fonction stripslashes_deep () de WordPress.
<?php stripslashes_deep($your_json);?>
Pour référence, visitez ici