34

This does not work:

$jsonDecode = json_decode($jsonData, TRUE);

However if I copy the string from $jsonData and put it inside the decode function manually it does work.

This works:

$jsonDecode = json_decode('{"id":"0","bid":"918","url":"http:\/\/www.google.com","md5":"6361fbfbee69f444c394f3d2fa062f79","time":"2014-06-02 14:20:21"}', TRUE);

I did output $jsonData copied it and put in like above in the decode function. Then it worked. However if I put $jsonData directly in the decode function it does not.

var_dump($jsonData) shows:

string(144) "{"id":"0","bid":"918","url":"http:\/\/www.google.com","md5":"6361fbfbee69f444c394f3d2fa062f79","time":"2014-06-02 14:20:21"}"

The $jsonData comes from a encrypted $_GET variable. To encrypt it I use this:

$key = "SOME KEY";

$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

$enc = mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $data, MCRYPT_MODE_ECB, $iv);

$iv = rawurlencode(base64_encode($iv));
$enc = rawurlencode(base64_encode($enc));

//To Decrypt
$iv = base64_decode(rawurldecode($_GET['i']));
$enc = base64_decode(rawurldecode($_GET['e']));

$data = mcrypt_decrypt(MCRYPT_BLOWFISH, $key, $enc, MCRYPT_MODE_ECB, $iv);
yoshi
  • 1,287
  • 3
  • 15
  • 28
  • 5
    Please show `var_dump($jsonData)`. – Barmar Jun 02 '14 at 19:00
  • 4
    In what way doesn't it work? What does it return? Do you have error reporting enabled, and are there any errors? – Barmar Jun 02 '14 at 19:01
  • where does the jsonData come from? – Rob Jun 02 '14 at 19:04
  • 2
    There must be some invisible characters in your data because `var_dump` indicates there are 144 characters but your string only has 124 visible characters. Can you post the raw data somewhere or check it in an hex editor? – laurent Jun 02 '14 at 19:12
  • @Rob $jsonData comes from a encrypted $_GET variable. – yoshi Jun 02 '14 at 19:13
  • 1
    When it fails, what does `json_last_error` return? http://us3.php.net/manual/en/function.json-last-error.php – thetaiko Jun 02 '14 at 19:19

18 Answers18

83

some time there is issue of html entities, for example \" it will represent like this \&quot, so you must need to parse the html entites to real text, that you can do using html_entity_decode() method of php.

$jsonData = stripslashes(html_entity_decode($jsonData));

$k=json_decode($jsonData,true);

print_r($k);
Bora
  • 10,529
  • 5
  • 43
  • 73
user2987827
  • 831
  • 1
  • 6
  • 2
18

You have to use preg_replace for avoiding the null results from json_decode

here is the example code

$json_string = stripslashes(html_entity_decode($json_string));
$bookingdata =  json_decode( preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $json_string), true ); 
Özgür Can Karagöz
  • 1,039
  • 1
  • 13
  • 32
Hassan Qasim
  • 463
  • 5
  • 5
13

Most likely you need to strip off the padding from your decrypted data. There are 124 visible characters in your string but var_dump reports 144. Which means 20 characters of padding needs to be removed (a series of "\0" bytes at the end of your string).

Probably that's 4 "\0" bytes at the end of a block + an empty 16-bytes block (to mark the end of the data).

How are you currently decrypting/encrypting your string?

Edit:

You need to add this to trim the zero bytes at the end of the string:

$jsonData = rtrim($jsonData, "\0");
laurent
  • 88,262
  • 77
  • 290
  • 428
  • That's probably it. I edited my question and added how I encrypt the the $jsonData. However I don't see anything wrong with the encryption. – yoshi Jun 02 '14 at 19:21
  • Could you also add how you decrypt the data? Encryption is fine but decryption seems to be where the problem is. – laurent Jun 02 '14 at 19:22
  • @user3630453, I've edited my answer. Adding the `rtrim` statement should fix the issue. – laurent Jun 02 '14 at 19:24
  • Many thanks! I know this might be unrelated to the question, but is this encryption ok? Or should I do it somehow else? – yoshi Jun 02 '14 at 19:33
  • @user3630453, ECB is not very secure (prefer CBC) because the same data is encrypted to the same ciphertext. For the cipher you might want to choose a variant of AES-256, such as MCRYPT_RIJNDAEL_256. There's an example here, which should work fine - http://stackoverflow.com/a/3422787/561309 – laurent Jun 02 '14 at 19:49
8

Judging from the other comments, you could use,

$jsonDecode = json_decode(trim($jsonData), TRUE);
Özgür Can Karagöz
  • 1,039
  • 1
  • 13
  • 32
dar7yl
  • 3,727
  • 25
  • 20
6

While moving on php 7.1 I encountered with json_decode error number 4 (json syntex error). None of the above solution on this page worked for me.

After doing some more searching i found solution at https://stackoverflow.com/a/15423899/1545384 and its working for me.

//Remove UTF8 Bom

function remove_utf8_bom($text)
{
    $bom = pack('H*','EFBBBF');
    $text = preg_replace("/^$bom/", '', $text);
    return $text;
}
Akhilesh Kumar
  • 849
  • 1
  • 15
  • 28
3

Be sure to set header to JSON

header('Content-type: application/json;');
A. Khaled
  • 1,468
  • 16
  • 28
2

Interestingly mcrypt_decrypt seem to add control characters other than \0 at the end of the resulting text because of its padding algorithm. Therefore instead of rtrim($jsonData, "\0") it is recommended to use

preg_replace( "/\p{Cc}*$/u", "", $data)

on the result $data of mcrypt_decrypt. json_decode will work if all trailing control characters are removed. Pl refer to the comment by Peter Bailey at http://php.net/manual/en/function.mdecrypt-generic.php .

2

str_replace("\t", " ", str_replace("\n", " ", $string))

because json_decode does not work with special characters. And no error will be displayed. Make sure you remove tab spaces and new lines. Depending on the source you get your data, you might need also: stripslashes(html_entity_decode($string))

Works for me:

<?php

$sql = <<<EOT

    SELECT *
        FROM `students`;

EOT;
    $string = '{ "query" : "' . str_replace("\t", " ", str_replace("\n", " ", $sql)).'" }';
    print_r(json_decode($string));

?>

output:

stdClass Object
(
    [query] =>          SELECT *      FROM `students`;     
)
profimedica
  • 2,716
  • 31
  • 41
2

I had problem that json_decode did not work, solution was to change string encoding to utf-8. This is important in case you have non-latin characters.

Thomas Smyth - Treliant
  • 4,993
  • 6
  • 25
  • 36
0

USE THIS CODE

<?php 
   $json = preg_replace('/[[:cntrl:]]/', '', $json_data);
   $json_array = json_decode($json, true);
   echo json_last_error();
   echo json_last_error_msg();
   print_r($json_array);
?>
Anil Rawat
  • 11
  • 2
0

Make sure your JSON is actually valid. For some reason I was convinced that this was valid JSON:

{ type: "block" }

While it is not. Point being, make sure to validate your string with a linter if you find json_decode not te be working.

Jules Colle
  • 11,227
  • 8
  • 60
  • 67
0

Try the JSON validator.

The problem in my case was it used ' not ", so I had to replace it to make it working.

luky
  • 2,263
  • 3
  • 22
  • 40
0

In notepad+ I changed encoding of json file on: "UTF-8 without BOM". JSON started to work

Vitalicus
  • 1,188
  • 13
  • 15
0

TL;DR Be sure that your JSON not containing comments :)

I've taken a JSON structure from API reference and tested request using Postman. I've just copy-pasted the JSON and didn't pay attention that there was a comment inside it:

...
"payMethod": {
    "type": "PBL" //or "CARD_TOKEN", "INSTALLMENTS"
},
...

Of course after deletion the comment json_decode() started working like a charm :)

Dzmitry Kulahin
  • 1,726
  • 2
  • 17
  • 21
0

I had an error when I sent from ajax sent JSON.stringify(localStorage.getItem('orderFormData')). json_decode worked as soon as I removed JSON.stringify and started sending just a string

  • This is more as comment or suggestion, not an answer perse, so I recommended you use the comment option instead. – Saul Uribe Mar 07 '23 at 01:30
-1

Use following function:

If JSON_ERROR_UTF8 occurred :

$encoded = json_encode( utf_convert( $responseForJS ) );

Below function is used to encode Array data recursively

/* Use it for json_encode some corrupt UTF-8 chars * useful for = malformed utf-8 characters possibly incorrectly encoded by json_encode */

function utf_convert( $mixed ) {
    if (is_array($mixed)) {
        foreach ($mixed as $key => $value) {
            $mixed[$key] = utf8ize($value);
        }
    } elseif (is_string($mixed)) {
        return mb_convert_encoding($mixed, "UTF-8", "UTF-8");
    }
    return $mixed;
}
-1

Maybe it helps someone, check in your json string if you have any NULL values, json_decode will not work if a NULL is present as a value.

This super basic function may help you. I made the NULL in an array just in case I need to add more stuff in the future.

function jsonValueFix($json){
    $json = str_replace( array('NULL'),'""',$json );
    return $json;
}
Oliver M Grech
  • 3,071
  • 1
  • 21
  • 36
-2

I just used json_decode twice and it worked for me

$response = json_decode($apiResponse, true);
$response = json_decode($response, true);
Ankit Kumar
  • 139
  • 8