WordPress rimuove i backslash di escape dalle stringhe JSON in post_meta

25 mag 2012, 23:39:35
Visualizzazioni: 15.4K
Voti: 19

Pensavo di semplificarmi la vita e di essere lungimirante salvando alcuni contenuti come frammenti JSON nei campi personalizzati post_meta. Sfortunatamente, WordPress non è d'accordo e sta rendendo la mia vita incredibilmente difficile.

Ho una stringa JSON che essenzialmente assomiglia a questa. Questo è solo un pezzo, e la stringa del commento è solo un insieme di entità unicode fittizie. Il tutto è generato con 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"
    }
}

Sfortunatamente, dopo averlo salvato con update_post_meta, risulta così:

{
    "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"
    }
}

E con gli slash rimossi, non può essere json_decodeato nuovamente in contenuto utile.

Qualche idea sul perché WordPress potrebbe comportarsi così e se esiste un modo per evitarlo? Non posso usare il flag JSON_UNESCAPED_UNICODE perché è un'installazione PHP 5.3.x, e ho già provato a codificare con htmlentities prima che il contenuto venga passato a json_encode, ma questo cattura solo un piccolo sottoinsieme di entità UTF-8.

Grazie in anticipo!

(EDIT: Per quel che vale, so che potrei semplicemente salvare un array direttamente in post_meta e verrebbe serializzato e accadrebbe la magia, ma mi piace l'idea di avere i dati memorizzati come JSON. Se non c'è una soluzione semplice ed elegante, mi arrenderò, ma spero davvero che ne esista una!)

0
Tutte le risposte alla domanda 8
5
36

C'è un modo elegante per gestire questo!

Passa la stringa codificata JSON attraverso wp_slash(). Questa funzione eseguirà l'escape dello slash iniziale di ogni carattere unicode codificato, il che impedirà a update_metadata() di rimuoverli.

9 gen 2014 19:20:40
Commenti

Questa è una soluzione alternativa per un grave bug di Wordpress. Grazie mille!

netAction netAction
7 giu 2017 10:18:55

Questa dovrebbe essere la risposta accettata. Ho avuto problemi con i contenuti importati da GitHub tramite wp_insert_post dove questo era un problema importante che rimuoveva gli slash dagli esempi di codice. Eseguire la stringa attraverso wp_slash prima di inviarla a wp_insert_post ha risolto il problema. Grazie!

Matt Keys Matt Keys
17 nov 2017 21:21:05

Questo è ancora utile anche oggi, ho perso ore e ore per trovare una soluzione alternativa a questo senza un solo indizio finché non ho trovato questo. Se vuoi aggiungere questa risposta alla mia domanda qui: https://stackoverflow.com/questions/61091853/wordpress-breaking-unicodes-when-saving-data la segnerò come risposta corretta. Grazie mille!

Jaypee Jaypee
8 apr 2020 07:02:54

Chi avrebbe pensato che un post di 8 anni fa potesse aiutarmi. Avevo problemi a salvare blocchi serializzati (Gutenberg), con attributi codificati in JSON a cui venivano rimossi gli slash. Eseguire l'output di serialize_block attraverso wp_slash ha risolto il problema.

Wouter van Vliet Wouter van Vliet
5 apr 2021 16:47:09

Dieci anni dopo, ho affrontato lo stesso problema usando wp_insert_post(), e questo ha salvato la mia giornata. Grazie!

Saulo Padilha Saulo Padilha
11 giu 2024 01:08:23
3
11

Sembra non ci sia modo di evitarlo.

La funzione update_metadata(), che è fondamentalmente responsabile per il salvataggio dei meta, esegue esplicitamente stripslashes_deep() sul valore del meta. Questa funzione rimuoverà anche gli slash dagli elementi degli array, se il valore fosse un array.

C'è un filtro che viene eseguito DOPO chiamato sanitize_meta, al quale potresti agganciarti. Ma a quel punto, i tuoi slash sono già stati rimossi, quindi non puoi determinare in modo affidabile dove dovevano essere reinseriti (o almeno, non so come potresti distinguere tra la citazione di delimitatori JSON legittimi e parti di valori).

Non posso dire perché lo faccia, ma lo fa. Probabilmente perché alla fine viene eseguito tramite wpdb->update, che ha bisogno delle stringhe senza escape.

Come temevi, probabilmente è meglio memorizzare il valore come un array, che verrà serializzato (come hai detto). Se lo vuoi come JSON in seguito, puoi semplicemente eseguirlo tramite json_encode().

26 mag 2012 00:18:44
Commenti

Avevo paura di questo, ma è bene sapere perché succede. Grazie mille per la risposta rapida!

Chris Van Patten Chris Van Patten
26 mag 2012 00:33:10

Questo non è vero, vedi le altre risposte :)

jave.web jave.web
6 mar 2015 16:51:07

@jave.web È vero che non puoi evitare che update_metadata() esegua strip slashes sulla tua stringa. Le altre risposte forniscono soluzioni alternative (molto intelligenti) per "doppiamente escape" la tua stringa, in modo che la rimozione inevitabile degli slash rimuova quelli aggiuntivi ma lasci intatti i tuoi slash originali. Personalmente direi ancora che il modo "elegante" per gestire questo è semplicemente memorizzare i dati in un array, che non richiede alcuna gestione speciale o pre-formattazione. Poi convertilo in json se e quando necessario. Ma questa è solo la mia preferenza.

MathSmath MathSmath
6 mag 2015 21:36:28
1

Puoi aggirare WordPress con qualcosa del genere:

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

Questa è davvero una soluzione semplice *ed elegante*...

1 ago 2012 13:36:28
Commenti

+1 Questo ha funzionato nel mio caso. Era un po' diverso da quello dell'OP, ma simile.

Adam Spriggs Adam Spriggs
1 ago 2018 14:43:16
0

Questa funzione esegue la trasformazione utilizzando preg_replace:

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

Prima di ogni sequenza "uXXXX" (dove X=0..F, esadecimale) aggiunge un backslash. Chiama questa funzione prima di inviare i dati al database.

19 gen 2017 12:04:27
0

Per chiunque abbia ancora difficoltà a salvare una stringa Unicode codificata in JSON tramite wp_update_post, quanto segue ha funzionato per me. Trovato in class-wp-rest-posts-controller.php

// converte l'oggetto post in un array, altrimenti wp_update_post si aspetterà un input non escapato.
wp_update_post( wp_slash( (array) $my_post ) ); 

Ecco un esempio:

$objectToEncodeToJson = array(
  'my_custom_key' => '<div>Ecco del HTML che verrà convertito in Unicode nel database.</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 ) );
8 mar 2019 22:38:58
0

Un modo interessante per aggirare questo problema è codificare in base64, vedi l'esempio qui sotto.

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

$to_json = json_encode($data);

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

$to_base64 =  base64_encode($to_json);

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

$back_to_json =  base64_decode($to_base64);

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

$back_to_aray = json_decode($back_to_json);

print_r($back_to_aray) ;
//stampa Array ( [0] => stdClass Object ( [name] => chris [URL] => hello.com ))
18 giu 2013 14:34:16
0

So che questa è una domanda vecchia, ma è ancora un problema che colpisce gli sviluppatori oggi. Quindi come riferimento, ecco una buona discussione dal tracker dei problemi del core di WordPress che ho trovato informativa: https://core.trac.wordpress.org/ticket/21767

21 mag 2024 14:54:55
1
-1

Puoi utilizzare la funzione WordPress stripslashes_deep().

<?php stripslashes_deep($your_json);?>

Per riferimento visita qui

25 gen 2017 09:49:31
Commenti

BARBJANE's viene ancora inviato da WordPress come BARBJANE\'s a meno che non mi stia sfuggendo qualcosa qui...

Si8 Si8
10 apr 2018 23:38:59