WordPress sta eliminando le barre rovesciate dalle stringhe JSON in post_meta


11

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

Ho una stringa JSON che assomiglia essenzialmente a questa. Questo è solo un bit e la stringa di commento è solo alcune entità unicode fittizie. Il tutto viene generato con il codice json .

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

Purtroppo dopo averlo salvato con update_post_meta, esce 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 le barre tagliate, non può essere json_decoderipristinato in contenuti utili.

Qualche idea sul perché WordPress potrebbe farlo, e se c'è un modo per evitarlo? Non riesco a usare il flag JSON_UNESCAPED_UNICODE perché si tratta di un'installazione di PHP 5.3.x e ho già provato a codificare htmlentitiesprima che il contenuto venga passato json_encode, ma che cattura solo un piccolo sottoinsieme di entità UTF-8.

Grazie in anticipo!

(EDIT: FWIW, so che potrei semplicemente salvare un array direttamente in post_meta e sarebbe serializzato e accadrà la magia, ma mi piace l'idea di avere i dati archiviati come JSON. Se non esiste una soluzione semplice ed elegante io grotta, ma io sono molto sperando che ci sia un modo facile, soluzione elegante!)

Risposte:


8

Non sembra che ci sia modo di evitarlo.

La funzione update_metadata (), che è in definitiva responsabile del salvataggio del meta, esegue esplicitamente un striplashes_deep () sul meta valore. Questa funzione eliminerà persino le barre dagli elementi dell'array, se il valore fosse un array.

C'è un filtro che viene eseguito DOPO che si chiama sanitize_meta, a cui puoi collegarti. Ma a quel punto, le tue barre sono già state rimosse, quindi non puoi determinare in modo affidabile dove dovevano essere aggiunte nuovamente (o almeno, non so come diresti la differenza tra la citazione dei delimitatori JSON legittimi rispetto ai bit di valori).

Non posso parlare del perché lo fa, ma lo fa. Probabilmente perché alla fine viene eseguito tramite wpdb-> update, che richiede le stringhe senza caratteri di escape.

Come temevi, probabilmente stai meglio archiviando il valore come un array, che verrà serializzato (come hai detto). Se lo desideri come JSON in un secondo momento, puoi semplicemente eseguirlo tramite json_encode ().


Ne avevo paura, ma è bello sapere perché sta accadendo. Grazie mille per la rapida risposta!
Chris Van Patten,

Questo non è vero, vedi altre risposte :)
jave.web

@ jave.web È vero che non puoi evitare che update_metadata () esegua barre di scorrimento sulla stringa. Le altre risposte forniscono soluzioni (molto intelligenti) per essenzialmente "raddoppiare" la tua stringa, in modo che l'inevitabile stripping rimuova quelle barre extra ma lascia intatte le tue barre originali. Personalmente direi ancora che il modo "elegante" di gestirlo è semplicemente archiviare i dati in un array, che non richiede alcuna gestione speciale o pre-formattazione. Quindi convertilo in json se e quando è necessario. Ma questa è solo la mia preferenza.
MathSmath,

25

C'è un modo elegante per gestirlo!

Passa la stringa codificata JSON wp_slash(). Tale funzione sfuggirà alla barra iniziale di ogni carattere unicode codificato, impedendo update_metadata()di rimuoverli.


Questa è una soluzione alternativa per un grave bug di Wordpress. Molte grazie!
netAzione

2
Questa dovrebbe essere la risposta accettata. Ho avuto problemi con il contenuto importato da GitHub tramite wp_insert_post, dove si trattava di un grave problema nella rimozione di barre dagli esempi di codice. Far funzionare la stringa attraverso wp_slash prima di inviarla tramite wp_insert_post ha funzionato. Grazie!
Matt Keys,

Questo è ancora utile anche oggi, ho perso ore e ore per trovare una soluzione per questo senza un singolo indizio fino a quando non l'ho trovato. Se vuoi aggiungere questa risposta alla mia domanda qui: stackoverflow.com/questions/61091853/… Lo segnerò come la risposta corretta. Grazie mille!
Jaypee,

4

Puoi imbrogliare in wordpress con qualcosa del genere:

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

Ciò è che facile * soluzione elegante * ...


+1 Questo ha fatto il trucco per la mia situazione. era un po 'diverso dall'OP, ma simile.
Adam Spriggs,

2

Questa funzione esegue la trasformazione usando 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" (X = 0..F, esadecimale) aggiunge una barra rovesciata. Prima di inviare al DB, chiamare questa funzione.


1

Un modo interessante per aggirare questo problema è codificare in base64, vedere l'esempio seguente.

$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

Per chiunque abbia ancora difficoltà a salvare una stringa unicode codificata json tramite wp_update_post , il seguente ha funzionato per me. Trovato in 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 ) ); 

Ecco un esempio:

$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

Puoi usare la funzione stripPress_leep () di WordPress.

<?php stripslashes_deep($your_json);?>

Per riferimento visita qui


BARBJANE'sviene ancora inviato da WordPress come BARBJANE\'sse non mi manchi qualcosa qui ...
Si8
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.