php 如何处理json字符串中的反斜杠php

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32056940/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 22:46:40  来源:igfitidea点击:

How to deal with backslashes in json strings php

phpjson

提问by Da Gopherboy

There appears to be an oddity with json_encode and/or json_decode when attempting decode a string that was produced by json_encode:

尝试解码由 json_encode 生成的字符串时,json_encode 和/或 json_decode 似乎有些奇怪:

    $object = new stdClass;
    $object->namespace = 'myCompany\package\subpackage';

    $jsonEncodedString = json_encode($object);
    echo $jsonEncodedString;
    // Result of echo being:
    // {"namespace":"myCompany\package\subpackage"}

    $anotherObject = json_decode($jsonEncodedString);
    echo $anotherObject->namespace;
    // Result of echo being:
    // myCompany\package\subpackage


    $yetAnotherObject = json_decode('{"namespace":"myCompany\package\subpackage"}');
    // Result should be:
    // myCompany\package\subpackage
    // But returns an invalid string sequence error instead...
    echo json_last_error_msg();

I've never experienced a problem previous to this, as I've never had to capture a string with backslashes in it until today. In reviewing the code above, I can encode/decode utilizing PHP's built in components. However if I attempt to decode a string that was produced by this encoder I get an error message. I've read in documentation items like "Predefined Constants" and other stack questions like "how remove the backslash (“\”) in the json response using php?". But I can't seem to find a reason WHY I can't decode a string that was produced by json_encode. The PHP version I'm using to test this code is 5.5.9.

在此之前我从未遇到过问题,因为直到今天我才必须捕获带有反斜杠的字符串。在查看上面的代码时,我可以使用 PHP 的内置组件进行编码/解码。但是,如果我尝试解码此编码器生成的字符串,则会收到一条错误消息。我读过文档项目,如“预定义常量”和其他堆栈问题,如“如何使用 php 删除 json 响应中的反斜杠(“\”)?”。但是我似乎找不到原因为什么我无法解码由 json_encode 生成的字符串。我用来测试此代码的 PHP 版本是 5.5.9。

I know I could be totally clueless by missing something, but should I be handling my string that was produced by json_encode differently if I attempt to use it elsewhere?

我知道我可能会因为遗漏某些东西而完全一无所知,但是如果我尝试在其他地方使用它,我是否应该以不同的方式处理由 json_encode 生成的字符串?

采纳答案by axiac

The answer is in the question:

答案在问题中:

$jsonEncodedString = json_encode($object);
echo $jsonEncodedString;
// Result of echo being:
// {"namespace":"myCompany\package\subpackage"}

You don't have to strip any slashes. On the contrary. You have to express the echo-ed text as PHP source code.

您不必去除任何斜线。相反。您必须将回显文本表示为 PHP 源代码。

$yetAnotherObject = json_decode('{"namespace":"myCompany\\package\\subpackage"}');

The backslash (\) is a special character in both PHP and JSON. Both languages use it to escape special characters in strings and in order to represent a backslash correctly in strings you have to prepend another backslash to it, both in PHP and JSON.

反斜杠 ( \) 是 PHP 和 JSON 中的特殊字符。两种语言都使用它来转义字符串中的特殊字符,并且为了在字符串中正确表示反斜杠,您必须在 PHP 和 JSON 中添加另一个反斜杠。

Let's try to do the job of the PHP parser on the string above. After the open parenthesis it encounters a string enclosed in single quotes. There are two special characters that needs escaping in single quote strings: the apostrophe (') and the backslash (\). While the apostrophe always needs escaping, the PHP interpreter is forgiving and allows unescaped backslashes as long as they do not create confusion. However, the correct representation of the backslash inside single quoted strings is \\.

让我们尝试在上面的字符串上完成 PHP 解析器的工作。在左括号之后,它遇到一个用单引号括起来字符串。单引号字符串中有两个特殊字符需要转义:撇号 ( ') 和反斜杠 ( \)。虽然撇号总是需要转义,但 PHP 解释器是宽容的,并允许未转义的反斜杠,只要它们不会造成混淆。但是,单引号字符串中反斜杠的正确表示是\\.

The string passed to function json_decode()is

传递给函数的字符串json_decode()

{"namespace":"myCompany\package\subpackage"}

Please note that this is the exact list of characters processed on runtime and not a string represented in PHP or any other language. The languages have special rules for representing special characters. This is just plain text.

请注意,这是在运行时处理的准确字符列表,而不是用 PHP 或任何其他语言表示的字符串。语言有表示特殊字符的特殊规则。这只是纯文本。

The text above is interpreted by function json_decode()that expects it to be a piece of JSON. JSONis a small language, it has special rules for encoding of special characters in strings. The backslash is one of these characters and when it appears in a string it must be prepended by another backslash. JSONis not forgiving; when it encounters a backslash it always treats it as an escape character for the next character in the string.

上面的文本由json_decode()期望它是JSON. JSON是一种小语言,它对字符串中特殊字符的编码有特殊的规则。反斜杠是这些字符之一,当它出现在字符串中时,必须在前面加上另一个反斜杠。JSON不宽容;当它遇到反斜杠时,它总是将其视为字符串中下一个字符的转义字符。

The object created by json_decode()after successful parsing of the JSON representation you pass them contains a single property named namespacewhose value is:

json_decode()在成功解析您传递给它们的 JSON 表示后创建的对象包含一个名为namespace的属性,其值为:

myCompany\package\subpackage

Note again that this is the actual string of characters and not a representation in any language.

再次注意,这是实际的字符串,而不是任何语言的表示。

What went wrong?

什么地方出了错?

Back to your code:

回到你的代码:

$yetAnotherObject = json_decode('{"namespace":"myCompany\package\subpackage"}');

The PHP parser interprets the code above using the PHP rules. It understands that the json_decode()function must be invoked with the text {"namespace":"myCompany\package\subpackage"}as argument.

PHP 解析器使用 PHP 规则解释上面的代码。它理解json_decode()必须使用文本{"namespace":"myCompany\package\subpackage"}作为参数调用该函数。

json_decode()uses its rules and tries to interpret the text above as a piece of JSON representation. The quote (") before myCompanytells it that "myCompany\package\subpackage"must be parsed as string. The backslash before packageis interpreted as an escape character for pbut \pis not a valid escape sequence for strings in JSON. This is why it refuses to continue and returns NULL.

json_decode()使用其规则并尝试将上面的文本解释为一段 JSON 表示。"前面的引号 ( )myCompany告诉它"myCompany\package\subpackage"必须解析为字符串。前面的反斜杠package被解释为转义字符,p\p不是 JSON 中字符串的有效转义序列。这就是它拒绝继续并返回的原因NULL

回答by Josh J

You will need to encode your double backslashes \\into quadruple backslashes \\\\because php interprets a backslash as an escape character in single and double quoted strings. This means that \\is seen as \.

您需要将双反斜杠编码\\为四重反斜杠,\\\\因为 php 将反斜杠解释为单引号和双引号字符串中的转义字符。这意味着\\被视为\.

This example illustrates what is happening

这个例子说明了正在发生的事情

<?php
$str = '{"namespace":"myCompany\package\subpackage"}';
echo $str, PHP_EOL; // \ seen as \
$yetAnotherObject = json_decode($str);
echo json_last_error_msg(), PHP_EOL;

var_dump(json_decode(str_replace('\', '\\', $str)));
echo json_last_error_msg(), PHP_EOL;

This is the output

这是输出

$ php test.php
{"namespace":"myCompany\package\subpackage"}
Syntax error
class stdClass#1 (1) {
  public $namespace =>
  string(28) "myCompany\package\subpackage"
}
No error

回答by sefodu

Please use the PHP native function stripslashes

请使用PHP原生函数 stripslashes

https://www.php.net/manual/en/function.stripslashes.php

https://www.php.net/manual/en/function.stripslashes.php

<?php
$str = 'myCompany\package\subpackage';
echo stripslashes(json_encode($str));
//output: myCompany\package\subpackage

回答by Blake A. Nichols

Thats because PHP is converting the double slashes into a single slash before passing it to json_decode. You will need to either escape the double slashes (a pain I know) or construct the object manually.

那是因为 PHP 在将它传递给 json_decode 之前将双斜杠转换为单斜杠。您将需要逃避双斜线(我知道这是一种痛苦)或手动构造对象。

http://php.net/manual/en/language.types.string.php#language.types.string.syntax.single

http://php.net/manual/en/language.types.string.php#language.types.string.syntax.single

回答by AleMelo

You can just use the stripslashesfunction to strip the dashes and it will work tested

您可以只使用stripslashes函数来去除破折号,它会 经过测试

  $yetAnotherObject = json_decode(stripslashes('{"namespace":"myCompany\package\subpackage"}'));