Reputation: 189
I recently upgraded to PHP 7.0.4 and nginx 1.8.1, my application uses the Zend Framework (Magento 1.9.2.1). Since that upgrade, our customers sometimes get an "Decoding failed: Syntax error" when submitting an orderm which is thrown in
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;
}
I read about a bug that PHP7 and JSON decode behaves differently when encoding an empty string. Does anyone know if this bug is related to PHP7 or to my application/server?
Thanks
Upvotes: 3
Views: 12811
Reputation: 667
I have the same problem. I have a temporary fix as follows, waiting for a better solution
//return Zend_Json::decode($data->params);
return json_decode($data->params);
Upvotes: 0
Reputation: 116
Dirty hack:
In my case it was a problem in Magento 2.2 with PHP7 where an empty object would throw an error. It would prevent the product indexer from completing.
So I added an empty array return for this case (in file 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) {
....
Upvotes: 0
Reputation: 1593
One possible (dirty) fix is to set the build in decoder of Zend to true, while this may be much slower this does work on PHP7 where the default package errors out.
in class Zend_Json
, set $useBuiltinEncoderDecoder
to true;
public static function decode($encodedValue, $objectDecodeType = Zend_Json::TYPE_ARRAY)
{
$encodedValue = (string) $encodedValue;
if (function_exists('json_decode') && self::$useBuiltinEncoderDecoder !== true) {
This way the return Zend_Json_Decoder::decode($encodedValue, $objectDecodeType);
will be used which seems to be working just fine.
Upvotes: 0
Reputation: 498
This is an absolutely normal behaviour of json_decode
.
It will throw this exception if the given string is not a valid JSON String.
As you already mentioned, an empty string is also not a valid JSON String.
json_decode('Hello') // invalid
json_decode("Hello") //invalid
But:
json_decode("'Hello'") // valid JSON string
Empty strings will raise an exception since 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."
So... to answer your question: In my opinion, your application has the problem you need to solve, if downgrading your PHP version is not an option.
The Magenta function needs to check for a valid representation of a JSON string BEFORE passing it to the json_decode
function.
Try to set the variable to {}
if it is not a string (is_string
) or if it is empty.
If this is not the problem, it might be possible that your string is not encoded as it should be. Many times encoding of the strings passed to json_decode
will result into that exception also.
Upvotes: 8