O WordPress está retirando barras invertidas de escape das strings JSON no post_meta


11

Eu pensei que estava facilitando minha vida e tendo consciência do futuro, salvando algum conteúdo como bits de JSON nos campos personalizados post_meta. Infelizmente, o WordPress não concorda e está tornando minha vida incrivelmente difícil.

Eu tenho uma string JSON que se parece essencialmente com isso. Isso é apenas um pouco, e a sequência de comentários é apenas algumas entidades unicode fictícias. A coisa toda é gerada com 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"
    }
}

Infelizmente, depois que eu o salvo update_post_meta, ele sai assim:

{
    "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 com as barras cortadas, não é possível json_decodevoltar ao conteúdo útil.

Alguma idéia de por que o WordPress pode estar fazendo isso, e se existe uma maneira de evitá-lo? Não posso usar o sinalizador JSON_UNESCAPED_UNICODE porque esta é uma instalação do PHP 5.3.x e já tentei codificar htmlentitiesantes da passagem do conteúdo json_encode, mas que captura apenas um pequeno subconjunto de entidades UTF-8.

Desde já, obrigado!

(EDIT: FWIW, eu sei que eu poderia salvar uma matriz diretamente no post_meta e seria serializada e a mágica aconteceria, mas eu apenas gosto da ideia de ter os dados armazenados como JSON. Se não houver uma solução fácil e elegante vou caverna, mas eu estou muito esperando lá é uma solução fácil, elegante!)

Respostas:


8

Parece que não há como evitá-lo.

A função update_metadata (), responsável por salvar a meta, executa explicitamente um stripslashes_deep () no valor da meta. Essa função removerá barras dos elementos da matriz, se o valor for uma matriz.

Existe um filtro que é executado APÓS chamado sanitize_meta, no qual você pode conectar. Mas, nesse ponto, suas barras já foram removidas, portanto, você não pode determinar com segurança onde elas precisam ser adicionadas novamente (ou pelo menos, não sei como saber a diferença entre citar delimitadores JSON legítimos x bits de valores).

Não posso falar sobre o porquê de fazer isso, mas faz. Provavelmente porque acabou rodando o wpdb-> update, que precisa das seqüências de caracteres sem escape.

Como você temia, provavelmente é melhor apenas armazenar o valor como uma matriz, que será serializada (como você disse). Se você desejar JSON posteriormente, basta executá-lo através de json_encode ().


Eu tinha medo disso, mas é bom saber por que está acontecendo. Muito obrigado pela resposta rápida!
Chris Van Patten

Este é nem verdadeira, consulte outras respostas :)
jave.web

@ jave.web É verdade que você não pode evitar que update_metadata () execute barras em sua string. As outras respostas fornecem soluções (muito inteligentes) para essencialmente "escapar duas vezes" sua string, para que a remoção inevitável remova essas barras extras, mas mantenha intactas as barras originais. Pessoalmente, ainda diria que a maneira "elegante" de lidar com isso é apenas armazenar dados em uma matriz, o que não requer tratamento especial ou pré-formatação. Em seguida, converta-o para json, se e quando for necessário. Mas essa é apenas a minha preferência.
MathSmath

25

Existe uma maneira elegante de lidar com isso!

Passe a string codificada em JSON wp_slash(). Essa função escapará da barra inicial de cada caractere unicode codificado, o que impedirá sua update_metadata()remoção.


Esta é uma solução alternativa para um bug sério do Wordpress. Muito obrigado!
netAction

2
Essa deve ser a resposta aceita. Eu tive problemas com o conteúdo sendo importado do GitHub por meio do wp_insert_post, onde esse era um problema importante na remoção de barras de amostras de código. Executar a sequência através do wp_slash antes de enviá-lo através do wp_insert_post fez o truque. Obrigado!
Matt Chaves

Isso ainda está sendo útil ainda hoje, perdi horas e horas para encontrar uma solução alternativa para isso sem uma única pista até encontrar isso. Se você quiser adicionar esta resposta à minha pergunta aqui: stackoverflow.com/questions/61091853/… Marcarei como a resposta correta. Muito obrigado!
Jaypee

4

Você pode trapacear no wordpress com algo assim:

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

Esta é a solução fácil * elegante * ...


+1 Isso fez o truque para a minha situação. era um pouco diferente do OP, mas semelhante.
Adam Spriggs

2

Esta função faz a transformação usando preg_replace:

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

Antes de cada sequência "uXXXX" (X = 0..F, hexadecimal), ela adiciona barra invertida. Antes de enviar para o DB, chame esta função.


1

Uma maneira interessante de contornar isso é codificar para base64, veja o exemplo abaixo.

$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

Para quem ainda está lutando para salvar uma string unicode codificada por json via wp_update_post , o seguinte funcionou para mim. Encontrado em 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 ) ); 

Aqui está um exemplo:

$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

Você pode usar a função stripslashes_deep () do WordPress.

<?php stripslashes_deep($your_json);?>

Para referência visite aqui


BARBJANE'sainda é enviada a partir do WordPress como BARBJANE\'sa menos que eu estou faltando alguma coisa aqui ...
Si8
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.