json_decode return NULL , UTF-8 BOM
Asked Answered
F

3

6

I want to decode the JSON data and store it in to an array using json_decode function but it's return NULL Value. I think it's because of UTF-8 BOM. Any Solution ? Im using Windows7 OS with xampp. I set my Encoding to

header('Content-type:application/json; charset=utf-8');

JSON DATA

{"command":"E101","user_id":"someuser","movie_id":"1","link_id":"2"}

JSON Error: Control character error, possibly incorrectly encoded

 $json_errors = array(
     JSON_ERROR_NONE => 'No error has occurred',
     JSON_ERROR_DEPTH => 'The maximum stack depth has been exceeded',
     JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded',
     JSON_ERROR_SYNTAX => 'Syntax error',
    );
    echo 'Last error : ', $json_errors[json_last_error()], PHP_EOL, PHP_EOL;

IF I Parse this JSON, No error Occured

 {"command":"E101","user_id":"someuser","movie_id":"movie_id","link_id":"link_id"}

The Only difference is Im storing string data in to movie_id and link_id . Why this happened ?

JSON Data Bin2Hex() 7b22636f6d6d616e64223a2245313031222c226d6f7669655f6964223a226d6f7669655f6964222c226c696e6b5f6964223a226c696e6b5f6964227d00000000

Im Encrypting the JSON data and via client side, im decrypting at the server side.

Here goes my Encryption function

    public function ajax_enc($data){

    $vector = "myvector";
    $filter = new Zend_Filter_Encrypt(array('adapter' => 'mcrypt', 'key' => $this->_AJAXKEY));
    $filter->setVector($vector);
    $encrypted = $filter->filter($data);
    // bin2hex for user use case     
    return bin2hex($encrypted); // rawurlencode(..) works

    }

Decrypt

public function ajax_dec($data)
{
$vector = "myvector";
$filter = new Zend_Filter_Decrypt(array('adapter' => 'mcrypt', 'key' => $this->_AJAXKEY ));
$filter->setVector($vector);
$decoded = pack('H*', $data);
$decrypted = $filter->filter($decoded);
return $decrypted;
}
Foregut answered 27/11, 2012 at 11:12 Comment(10)
Where is the data coming from exactly?Glooming
@pekka from the Client side using jquery $.ajax();Foregut
Can you show more code? The exact Ajax statement and the PHP code where you do the json_decodeGlooming
If it is BOM, try to run if (substr($string, 0,3) == pack("CCC",0xef,0xbb,0xbf)) { $string = substr($string, 3); }Hobard
@nkamn I tried this, didn't workForegut
@pekka in Ajax post JSON data is encrypted using the Zend_Filter_Encrypt(array('adapter' => 'mcrypt', 'key' => "MYKEY" )) and at the server side i decrypt the data into Valid JSON.Foregut
I don't follow what you are doing here. You will need to show some more code. (You can edit it into your question)Glooming
@Hobard "\xEF\xBB\xBF" - No need for pack.Reentry
Is there any other PHP JSON parser library available ? i don't want to use json_encode,json_decode anymore.Foregut
If the JSON is valid, json_decode can usually parse it just fine. Show us a bin2hex of your supposed JSON. Especially since you're en- and decrypting it, I wouldn't be surprised about some stray bits which don't belong there.Reentry
R
3

Your decryption has apparently left a bunch of padding NUL bytes at the end of the string.

Either fix your decryption mechanism or trim them: trim($json, "\x0")

Reentry answered 27/11, 2012 at 13:50 Comment(2)
Thank you very much , You solved it , Are you sure this will work every time for all the json strings ?Foregut
There should be no NUL bytes at the beginning or end of any JSON strings. So, yes, as far as NUL bytes go, this should work.Reentry
I
2

To remove  do:

$json_raw_str = ltrim($json_raw_str, chr(239).chr(187).chr(191));

Why? Because Byte_order_mark 239 187 191 is the decimal representation of  and ltrim remove them from the begining of the string.

After this do:

$data = json_decode($json_raw_str);
// be fun :)
Insolate answered 2/8, 2019 at 23:9 Comment(3)
It is difficult to understand why your answer might work. Using comments in the solution is probably not the best way to add an explanation. Can you add an explanation of what you think the OP's issue is and why this fixes it?Farman
@DCTID, feel free to edit posts into shape. Leonan, I'm also not understanding how your solution is related to the question presented... (?)Corene
This worked correctly. Check if indeed this is the problem first - https://mcmap.net/q/86797/-how-do-i-see-the-current-encoding-of-a-file-in-sublime-text - and then use this fix.Origin
P
0

This worked for me (it removes the BOM):

$json = json_decode(ltrim($jsonString, "\xEF\xBB\xBF"), true);
Periphrastic answered 7/11, 2022 at 12:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.