WordPress entfernt Escape-Backslashes von JSON-Strings in post_meta

11

Ich dachte, ich würde mir das Leben leichter machen und zukunftsbewusst sein, indem ich einige Inhalte als JSON-Teile in benutzerdefinierten post_meta-Feldern speichere. Leider stimmt WordPress nicht zu und macht mein Leben unglaublich schwierig.

Ich habe eine JSON-Zeichenfolge, die im Wesentlichen so aussieht. Dies ist nur ein Bit, und die Kommentarzeichenfolge besteht nur aus einigen Dummy-Unicode-Entitäten. Das Ganze wird mit json_encode generiert .

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

Nachdem ich es mit update_post_metagespeichert habe, sieht es leider so aus:

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

Und wenn die Schrägstriche entfernt sind, kann es nicht json_decodewieder in nützliche Inhalte umgewandelt werden.

Irgendwelche Ideen, warum WordPress dies tun könnte und ob es einen Weg gibt, dies zu vermeiden? Ich kann das JSON_UNESCAPED_UNICODE-Flag nicht verwenden, da dies eine PHP 5.3.x-Installation ist und ich bereits versucht habe, mit zu codieren, htmlentitiesbevor der Inhalt an übergeben wird json_encode, aber dies erfasst nur eine kleine Teilmenge von UTF-8-Entitäten.

Danke im Voraus!

(EDIT: FWIW, ich weiß, ich könnte ein Array einfach direkt in post_meta speichern und es würde serialisiert und Magie würde passieren, aber ich mag nur die Idee, die Daten als JSON zu speichern. Wenn es keine einfache, elegante Lösung gibt ich werde Höhle, aber ich bin sehr viel Hoffnung , es ist eine einfache, elegante Lösung!)

Chris Van Patten
quelle

Antworten:

7

Sieht nicht so aus, als gäbe es eine Möglichkeit, dies zu vermeiden.

Die Funktion update_metadata (), die letztendlich für das Speichern des Metas verantwortlich ist, führt explizit ein stripslashes_deep () für den Metawert aus. Diese Funktion entfernt sogar Schrägstriche von Array-Elementen, wenn der Wert ein Array wäre.

Es gibt einen Filter, der NACH dem Namen sanitize_meta ausgeführt wird und an den Sie sich anschließen können. Aber zu diesem Zeitpunkt wurden Ihre Schrägstriche bereits entfernt, sodass Sie nicht zuverlässig bestimmen können, wo sie wieder hinzugefügt werden müssen (oder zumindest weiß ich nicht, wie Sie den Unterschied zwischen dem Zitieren legitimer JSON-Trennzeichen und Bits erkennen würden von Werten).

Ich kann nicht sagen, warum es das tut, aber es tut es. Wahrscheinlich, weil es irgendwann durch wpdb-> update läuft, wo die Strings entkoppelt werden müssen.

Wie Sie befürchtet haben, ist es wahrscheinlich besser, den Wert nur als Array zu speichern, das (wie gesagt) serialisiert wird. Wenn Sie es später als JSON möchten, können Sie es einfach über json_encode () ausführen.

MathSmath
quelle
Ich hatte Angst davor, aber es ist gut zu wissen, warum es passiert. Vielen Dank für die schnelle Antwort!
Chris Van Patten
Dies ist nicht wahr, siehe andere Antworten :)
jave.web
@ jave.web Es ist wahr, dass Sie nicht vermeiden können, dass update_metadata () Schrägstriche auf Ihrer Zeichenfolge ausführt. Die anderen Antworten bieten (sehr intelligente) Problemumgehungen, um Ihre Zeichenfolge im Wesentlichen doppelt zu "entkommen", sodass durch das unvermeidbare Entfernen diese zusätzlichen Schrägstriche entfernt werden, Ihre ursprünglichen Schrägstriche jedoch intakt bleiben. Ich persönlich würde immer noch sagen, dass die "elegante" Art, dies zu handhaben, darin besteht, Daten nur in einem Array zu speichern, was keine spezielle Behandlung oder Vorformatierung erfordert. Konvertieren Sie es dann in json, wenn und wann Sie müssen. Aber das ist nur meine Präferenz.
MathSmath
24

Es gibt eine elegante Möglichkeit, damit umzugehen!

Führen Sie die JSON-codierte Zeichenfolge durch wp_slash(). Diese Funktion entgeht dem führenden Schrägstrich jedes codierten Unicode-Zeichens, wodurch verhindert wird, dass update_metadata()sie entfernt werden.

jkereako
quelle
Dies ist eine Problemumgehung für einen schwerwiegenden Wordpress-Fehler. Vielen Dank!
netAction
2
Dies sollte die akzeptierte Antwort sein. Ich hatte Probleme mit dem Import von Inhalten aus GitHub über wp_insert_post, wobei dies ein Hauptproblem beim Entfernen von Schrägstrichen aus Codebeispielen war. Das Ausführen der Zeichenfolge durch wp_slash vor dem Senden durch wp_insert_post hat den Trick ausgeführt. Vielen Dank!
Matt Keys
Dies ist auch heute noch nützlich. Ich habe Stunden und Stunden verloren, um eine Problemumgehung dafür zu finden, ohne einen einzigen Hinweis, bis ich dies gefunden habe. Wenn Sie diese Antwort zu meiner Frage hier hinzufügen möchten: stackoverflow.com/questions/61091853/… Ich werde sie als die richtige Antwort markieren. Ich danke dir sehr!
Jaypee
4

Sie können WordPress mit so etwas betrügen:

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

Dies ist diese einfache * elegante Lösung * ...

drmartin
quelle
+1 Das hat den Trick für meine Situation getan. es war ein wenig anders als das OP, aber ähnlich.
Adam Spriggs
2

Diese Funktion führt die Transformation mit preg_replace durch:

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

Vor jeder "uXXXX" -Sequenz (X = 0..F, hexadezimal) wird ein Backslash hinzugefügt. Rufen Sie diese Funktion auf, bevor Sie sie an DB senden.

Florin Chis
quelle
1

Ein interessanter Weg, dies zu umgehen, ist die Codierung in base64 (siehe Beispiel unten).

$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 ))
David Allen
quelle
1

Für alle, die immer noch Probleme haben , eine json-codierte Unicode-Zeichenfolge über wp_update_post zu speichern , hat das Folgende für mich funktioniert. Gefunden 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 ) ); 

Hier ist ein Beispiel:

$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 ) );
gbones
quelle
-1

Sie können die WordPress-Funktion stripslashes_deep () verwenden.

<?php stripslashes_deep($your_json);?>

Als Referenz besuchen Sie hier

Irfan Bin Hakim
quelle
BARBJANE'swird immer noch von WordPress gesendet, als BARBJANE\'s
ob