我遇到了一个非常奇怪的问题。
我有一个JSON网络服务。
当我在本网站http://www.freeformatter.com/json-formatter.html#ad-output
上查看时一切都好。
但是当我用这段代码加载我的JSON时:
$data = file_get_contents('http://www.mywebservice');
if(!empty($data))
{
$obj = json_decode($data);
switch (json_last_error()) {
case JSON_ERROR_NONE:
echo ' - JSON_ERROR_NONE';
break;
case JSON_ERROR_DEPTH:
echo ' - JSON_ERROR_DEPTH';
break;
case JSON_ERROR_STATE_MISMATCH:
echo ' - JSON_ERROR_STATE_MISMATCH';
break;
case JSON_ERROR_CTRL_CHAR:
echo ' - JSON_ERROR_CTRL_CHAR';
break;
case JSON_ERROR_SYNTAX:
echo "\r\n\r\n - SYNTAX ERROR \r\n\r\n";
break;
case JSON_ERROR_UTF8:
echo ' - JSON_ERROR_UTF8';
break;
default:
echo ' - Unknown erro';
break;
}
我收到错误:SYNTAX ERROR
一切都没有完全帮助。
这是一场噩梦。
我看到使用PHP 5.5我可以使用此功能:http://php.net/manual/en/function.json-last-error-msg.php
(但我还没有成功安装PHP 5.5,我不确定这个功能会给我更多细节)
答案 0 :(得分:72)
我遇到了同样的问题,实际上有一些看不见的隐藏字符,你需要删除它。 这是一个适用于许多情况的全局代码:
<?php
$checkLogin = file_get_contents("http://yourwebsite.com/JsonData");
// This will remove unwanted characters.
// Check http://www.php.net/chr for details
for ($i = 0; $i <= 31; ++$i) {
$checkLogin = str_replace(chr($i), "", $checkLogin);
}
$checkLogin = str_replace(chr(127), "", $checkLogin);
// This is the most common part
// Some file begins with 'efbbbf' to mark the beginning of the file. (binary level)
// here we detect it and we remove it, basically it's the first 3 characters
if (0 === strpos(bin2hex($checkLogin), 'efbbbf')) {
$checkLogin = substr($checkLogin, 3);
}
$checkLogin = json_decode( $checkLogin );
print_r($checkLogin);
?>
答案 1 :(得分:41)
删除BOM
(字节顺序标记)通常是您需要的解决方案:
function removeBOM($data) {
if (0 === strpos(bin2hex($data), 'efbbbf')) {
return substr($data, 3);
}
return $data;
}
你不应该有一张BOM,但如果它有,那就是看不见的,所以你不会看到它!!
如果您要修复很多文件,请使用BOM Cleaner。
答案 2 :(得分:27)
我解决了这个问题,在json_decode之前将 stripslashes 添加到字符串中。
$data = stripslashes($data);
$obj = json_decode($data);
答案 3 :(得分:6)
为了把所有东西放在一起,我已经准备好JSON包装器,解码自动纠正措施。最新版本可以在我的GitHub Gist。
中找到abstract class Json
{
public static function getLastError($asString = FALSE)
{
$lastError = \json_last_error();
if (!$asString) return $lastError;
// Define the errors.
$constants = \get_defined_constants(TRUE);
$errorStrings = array();
foreach ($constants["json"] as $name => $value)
if (!strncmp($name, "JSON_ERROR_", 11))
$errorStrings[$value] = $name;
return isset($errorStrings[$lastError]) ? $errorStrings[$lastError] : FALSE;
}
public static function getLastErrorMessage()
{
return \json_last_error_msg();
}
public static function clean($jsonString)
{
if (!is_string($jsonString) || !$jsonString) return '';
// Remove unsupported characters
// Check http://www.php.net/chr for details
for ($i = 0; $i <= 31; ++$i)
$jsonString = str_replace(chr($i), "", $jsonString);
$jsonString = str_replace(chr(127), "", $jsonString);
// Remove the BOM (Byte Order Mark)
// It's the most common that some file begins with 'efbbbf' to mark the beginning of the file. (binary level)
// Here we detect it and we remove it, basically it's the first 3 characters.
if (0 === strpos(bin2hex($jsonString), 'efbbbf')) $jsonString = substr($jsonString, 3);
return $jsonString;
}
public static function encode($value, $options = 0, $depth = 512)
{
return \json_encode($value, $options, $depth);
}
public static function decode($jsonString, $asArray = TRUE, $depth = 512, $options = JSON_BIGINT_AS_STRING)
{
if (!is_string($jsonString) || !$jsonString) return NULL;
$result = \json_decode($jsonString, $asArray, $depth, $options);
if ($result === NULL)
switch (self::getLastError())
{
case JSON_ERROR_SYNTAX :
// Try to clean json string if syntax error occured
$jsonString = self::clean($jsonString);
$result = \json_decode($jsonString, $asArray, $depth, $options);
break;
default:
// Unsupported error
}
return $result;
}
}
使用示例:
$json_data = file_get_contents("test.json");
$array = Json::decode($json_data, TRUE);
var_dump($array);
echo "Last error (" , Json::getLastError() , "): ", Json::getLastError(TRUE), PHP_EOL;
答案 4 :(得分:2)
就我而言:
json_decode(html_entity_decode($ json_string));
答案 5 :(得分:2)
请先清除json数据,然后加载。
答案 6 :(得分:1)
你没有显示你的JSON,但这听起来像是参数中的无效UTF-8序列,大多数在线验证器都不会捕获它。 确保您的数据是UTF-8,并检查您是否有外国字符。 您不需要PHP5来查看错误,请使用error_log()来记录问题。
答案 7 :(得分:1)
我也面临这个问题,这让我感到沮丧。经过数小时尝试在互联网上使用其他解决方案。我注意到文件的编码是在 UTF-8中且带有BOM ,因为var_dump()在JSON之前回显了一个奇怪的字符&#65279; 。
我将正在使用的sample.json文件从具有BOM表的 UTF-8 转换为 UTF-8 ...在VS CODE中,将以下内容添加到您的设置中.json或确保以下设置代码如下所示(默认情况下,您创建的任何文件都将以UTF-8编码;
"files.encoding": "utf8",
然后,您将在VSCode工具栏上看到类似以下屏幕截图的内容。 (要使json_decode()
正常工作,文件必须使用UTF-8编码)
但是在我的情况下,我创建的JSON文件使用的是 UTF-8和BOM 编码,这就是为什么当我执行json_decode($json, true)
时它返回null(当我出现语法错误时var_dump(json_last_error_msg())
)
这将使用UTF-8编码重新保存文件,您可以继续检查代码。 json_decode()
可以正常工作。不敢相信我花了数小时试图找出可能出问题的地方。
快乐编码!
答案 8 :(得分:1)
尝试了所有解决方案但没有结果之后,这对我来说就是一个解决方法。
希望它将对某人有所帮助
$data = str_replace('"', '"', $data);
答案 9 :(得分:1)
我遇到了同样的问题,收到了 JSON_ERROR_CTRL_CHAR 和 JSON_ERROR_SYNTAX 。
这是我的解决方法。
$content = json_decode(json_encode($content), true);
答案 10 :(得分:1)
JSON字符串必须用双引号引起来,JSON无效,因为您不需要转义'
字符。
char = unescaped /
escape (
%x22 / ; " quotation mark U+0022
%x5C / ; \ reverse solidus U+005C
%x2F / ; / solidus U+002F
%x62 / ; b backspace U+0008
%x66 / ; f form feed U+000C
%x6E / ; n line feed U+000A
%x72 / ; r carriage return U+000D
%x74 / ; t tab U+0009
%x75 4HEXDIG ) ; uXXXX U+XXXX
'
不在列表中。
请参阅以下用于JSON的特殊字符列表:
\b Backspace (ascii code 08)
\f Form feed (ascii code 0C)
\n New line
\r Carriage return
\t Tab
\" Double quote
\\ Backslash character
访问this网站以获取更多文档。
答案 11 :(得分:0)
我遇到了同样的问题,原因是响应的文本看起来像json,但实际上是HTML格式的文本。您可以以JSON格式回显文本(类似于json),以查看内部的实际内容:
$response = file_get_contents('http://www.mywebservice');
header('Content-Type: application/json');
echo $response;
此函数 file_get_contents 将返回一些额外的HTML代码。 就我而言,我删除了那些不需要的字符:
$response = str_replace('<head></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">', '',$response );
$response = str_replace('</pre></body>', '',$response );
这是完整的代码:
$response = file_get_contents('http://www.mywebservice');
$response = str_replace('<head></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">', '',$response );
$response = str_replace('</pre></body>', '',$response );
$response = json_decode($response);
header('Content-Type: application/json');
$error = json_last_error_msg() ;
echo $error;
if ($error == null){echo "This is truly a JSON : <br>"}
echo $response;
答案 12 :(得分:0)
此代码对我有用。 基本上,它会删除隐藏的字符。
function cleanString($val)
{
$non_displayables = array(
'/%0[0-8bcef]/', # url encoded 00-08, 11, 12, 14, 15
'/%1[0-9a-f]/', # url encoded 16-31
'/[\x00-\x08]/', # 00-08
'/\x0b/', # 11
'/\x0c/', # 12
'/[\x0e-\x1f]/', # 14-31
'/x7F/' # 127
);
foreach ($non_displayables as $regex)
{
$val = preg_replace($regex,'',$val);
}
$search = array("\0","\r","\x1a","\t");
return trim(str_replace($search,'',$val));
}
答案 13 :(得分:0)
我这边的一个问题是,有一些以0开头的无效数字,例如:“ 001”,“ 002”,“ 003”。
"expectedToBeReturned":1,
"inventoryNumber":001,
"remindNote":"",
将001替换为1即可。
答案 14 :(得分:0)
我有同样的问题。我采取了以下步骤:
更改了JSON文本编码
$json = utf8_encode($json);
然后我在解码之前查看了纯文本。我发现了
这样的疯狂符号 ï
然后我将其剥离
$json = str_replace(array('ï',''), '',$json);
我成功解码了JSON
答案 15 :(得分:-1)
我有同样的问题。对我来说,这是由echo "<br/><pre>"
造成的。
我试图使用以下命令将json字符串传递给另一个php文件:
exit(json_encode(utf8ize($resp_array)));
在文件开头我已经删除了断行标记...所以这对我来说是错误的。删除此断行标记,我能够[...]
答案 16 :(得分:-1)
我有同样的问题。对我来说,这是由echo "<br/><pre>"
造成的。我试图使用exit(json_encode(utf8ize($resp_array)));
将json字符串传递给另一个php文件。在文件开头我已经删除 break line 标签...所以这对我来说是错误的。删除此断行标记,我能够将我的json字符串解码为另一个php文件..