PHP7、JSON和Zend(解码失败:语法错误)
PHP7, JSON and Zend (decoding failed: syntax error)
我最近升级到 PHP 7.0.4 和 nginx 1.8.1,我的应用程序使用 Zend Framework (Magento 1.9.2.1)。自那次升级以来,我们的客户有时会在提交
中抛出的订单时收到 "Decoding failed: Syntax error"
public static function decode($encodedValue, $objectDecodeType = Zend_Json::TYPE_ARRAY)
{
$encodedValue = (string) $encodedValue;
if (function_exists('json_decode') && self::$useBuiltinEncoderDecoder !== true) {
$decode = json_decode($encodedValue, $objectDecodeType);
// php < 5.3
if (!function_exists('json_last_error')) {
if (strtolower($encodedValue) === 'null') {
return null;
} elseif ($decode === null) {
#require_once 'Zend/Json/Exception.php';
throw new Zend_Json_Exception('Decoding failed');
}
// php >= 5.3
} elseif (($jsonLastErr = json_last_error()) != JSON_ERROR_NONE) {
#require_once 'Zend/Json/Exception.php';
switch ($jsonLastErr) {
case JSON_ERROR_DEPTH:
throw new Zend_Json_Exception('Decoding failed: Maximum stack depth exceeded');
case JSON_ERROR_CTRL_CHAR:
throw new Zend_Json_Exception('Decoding failed: Unexpected control character found');
case JSON_ERROR_SYNTAX:
throw new Zend_Json_Exception('Decoding failed: Syntax error');
default:
throw new Zend_Json_Exception('Decoding failed');
}
}
return $decode;
}
我了解到 PHP7 和 JSON 编码空字符串时解码行为不同的错误。有谁知道这个错误是否与 PHP7 或我的 application/server 有关?
谢谢
这是 json_decode
的绝对正常行为。
如果给定的字符串不是有效的 JSON 字符串,它将抛出此异常。
正如您已经提到的,空字符串也不是有效的 JSON 字符串。
json_decode('Hello') // invalid
json_decode("Hello") //invalid
但是:
json_decode("'Hello'") // valid JSON string
空字符串将引发异常,因为 PHP7!
"Calling json_decode with 1st argument equal to empty PHP string or value that after casting to string is empty string (NULL, FALSE) results in JSON syntax error."
所以...回答你的问题:在我看来,如果不能降级你的 PHP 版本,你的应用程序有你需要解决的问题。
Magenta 函数需要在将 JSON 字符串传递给 json_decode
函数之前检查它的有效表示形式。
如果变量不是字符串 (is_string
) 或为空,请尝试将变量设置为 {}
。
如果这不是问题所在,则可能是您的字符串未按应有的方式编码。很多时候对传递给 json_decode
的字符串进行编码也会导致该异常。
一个可能的(肮脏的)修复是将 Zend 的内置解码器设置为 true,虽然这可能会慢得多,但这确实适用于 PHP7 默认包出错的地方。
在classZend_Json
中,设置$useBuiltinEncoderDecoder
为真;
public static function decode($encodedValue, $objectDecodeType = Zend_Json::TYPE_ARRAY)
{
$encodedValue = (string) $encodedValue;
if (function_exists('json_decode') && self::$useBuiltinEncoderDecoder !== true) {
这样 return Zend_Json_Decoder::decode($encodedValue, $objectDecodeType);
将被使用,这似乎工作得很好。
肮脏的技巧:
就我而言,这是 Magento 2.2 中的一个问题 PHP7,空对象会引发错误。它会阻止产品索引器完成。
所以我为这种情况添加了一个空数组 return(在文件 vendor/magento/zendframework1/library/Zend/Json.php 中):
public static function decode($encodedValue, $objectDecodeType = Zend_Json::TYPE_ARRAY)
{
$encodedValue = (string) $encodedValue;
if($encodedValue == "a:0:{}") { return []; } //<- added: return an empty array
if (function_exists('json_decode') && self::$useBuiltinEncoderDecoder !== true) {
....
我也遇到了同样的问题。我有一个临时修复如下,等待更好的解决方案
//return Zend_Json::decode($data->params);
return json_decode($data->params);
这已在 zend-mvc 3.1.1 中修复
我最近升级到 PHP 7.0.4 和 nginx 1.8.1,我的应用程序使用 Zend Framework (Magento 1.9.2.1)。自那次升级以来,我们的客户有时会在提交
中抛出的订单时收到 "Decoding failed: Syntax error"public static function decode($encodedValue, $objectDecodeType = Zend_Json::TYPE_ARRAY)
{
$encodedValue = (string) $encodedValue;
if (function_exists('json_decode') && self::$useBuiltinEncoderDecoder !== true) {
$decode = json_decode($encodedValue, $objectDecodeType);
// php < 5.3
if (!function_exists('json_last_error')) {
if (strtolower($encodedValue) === 'null') {
return null;
} elseif ($decode === null) {
#require_once 'Zend/Json/Exception.php';
throw new Zend_Json_Exception('Decoding failed');
}
// php >= 5.3
} elseif (($jsonLastErr = json_last_error()) != JSON_ERROR_NONE) {
#require_once 'Zend/Json/Exception.php';
switch ($jsonLastErr) {
case JSON_ERROR_DEPTH:
throw new Zend_Json_Exception('Decoding failed: Maximum stack depth exceeded');
case JSON_ERROR_CTRL_CHAR:
throw new Zend_Json_Exception('Decoding failed: Unexpected control character found');
case JSON_ERROR_SYNTAX:
throw new Zend_Json_Exception('Decoding failed: Syntax error');
default:
throw new Zend_Json_Exception('Decoding failed');
}
}
return $decode;
}
我了解到 PHP7 和 JSON 编码空字符串时解码行为不同的错误。有谁知道这个错误是否与 PHP7 或我的 application/server 有关?
谢谢
这是 json_decode
的绝对正常行为。
如果给定的字符串不是有效的 JSON 字符串,它将抛出此异常。
正如您已经提到的,空字符串也不是有效的 JSON 字符串。
json_decode('Hello') // invalid
json_decode("Hello") //invalid
但是:
json_decode("'Hello'") // valid JSON string
空字符串将引发异常,因为 PHP7!
"Calling json_decode with 1st argument equal to empty PHP string or value that after casting to string is empty string (NULL, FALSE) results in JSON syntax error."
所以...回答你的问题:在我看来,如果不能降级你的 PHP 版本,你的应用程序有你需要解决的问题。
Magenta 函数需要在将 JSON 字符串传递给 json_decode
函数之前检查它的有效表示形式。
如果变量不是字符串 (is_string
) 或为空,请尝试将变量设置为 {}
。
如果这不是问题所在,则可能是您的字符串未按应有的方式编码。很多时候对传递给 json_decode
的字符串进行编码也会导致该异常。
一个可能的(肮脏的)修复是将 Zend 的内置解码器设置为 true,虽然这可能会慢得多,但这确实适用于 PHP7 默认包出错的地方。
在classZend_Json
中,设置$useBuiltinEncoderDecoder
为真;
public static function decode($encodedValue, $objectDecodeType = Zend_Json::TYPE_ARRAY)
{
$encodedValue = (string) $encodedValue;
if (function_exists('json_decode') && self::$useBuiltinEncoderDecoder !== true) {
这样 return Zend_Json_Decoder::decode($encodedValue, $objectDecodeType);
将被使用,这似乎工作得很好。
肮脏的技巧:
就我而言,这是 Magento 2.2 中的一个问题 PHP7,空对象会引发错误。它会阻止产品索引器完成。
所以我为这种情况添加了一个空数组 return(在文件 vendor/magento/zendframework1/library/Zend/Json.php 中):
public static function decode($encodedValue, $objectDecodeType = Zend_Json::TYPE_ARRAY)
{
$encodedValue = (string) $encodedValue;
if($encodedValue == "a:0:{}") { return []; } //<- added: return an empty array
if (function_exists('json_decode') && self::$useBuiltinEncoderDecoder !== true) {
....
我也遇到了同样的问题。我有一个临时修复如下,等待更好的解决方案
//return Zend_Json::decode($data->params);
return json_decode($data->params);
这已在 zend-mvc 3.1.1 中修复