Search code examples
phpmysqljsonselect-insert

MySQL JSON Encoded string corrupts after INSERT..SELECT


I'm encoding array of Image URLS into json string and store them in database. (utf8_general_ci).

When I insert data into table and retrive it, json_decode() is capable of decoding it.

However, when I copy data from one table to another (INSERT INTO ... SELECT statement) data after retrieving from database cannot be decoded anymore.

Instead, i get corrupted json ENCoded string. Even empty array [] cannot be properly decoded.

It converts from http://pl.tinypic.com/r/fwoiol/8 into http://pl.tinypic.com/r/bgea05/8

(had to make images since those squares cannot be copied as text).

Edit, After checking a bit more i tried to bin2hex() both strings from database.

Both seem to be exactly same.

However, one decodes and one does not. The

5b22687474703a5c2f5c2f7777772e
changes into
0022687474703a5c2f5c2f7777772e

So, json_decode only changes 5b into 00 in string.

It's like It's losing encoding somewhere?

Edit 2

static public function jsonDecodeFieldsArray($entries, $fields = array('features','images')){
    foreach($entries as $key => $entry){
        $entries[$key] = self::jsonDecodeFields($entry, $fields);
    }
    return $entries;
}
static public function jsonDecodeFields($entry, $fields = array('features','images')){
    foreach($fields as $field){
        if(isset($entry[$field])){
            $entry[$field] = json_decode((string) $entry[$field], true);
        }
    }
    return $entry;
}

I'm using code above, to decode keys of array specified by $fields. However, it not only decodes wrongfully. But also affects keys that are not listed in $fields. Corrupting their encodings.

More to add. If I dont use those functions and use only json_decode on fields json_decode($array[0][images], true) it works fine.


Solution

  • To Clarify that I found answer/solution I write this Answer

    The reason behoind this error was not SQL error and data was proper. I had an example array of:

    $many_entries = array(
        array(
            'features' = > 'json_encoded_string'
            'images' = > 'json_encoded_string'
        ),
        array(
            'features' = > 'json_encoded_string'
            'images' = > 'json_encoded_string'
        )
    
    );
    // And 
    $one_entry = array(
        'features' = > 'json_encoded_string'
        'images' = > 'json_encoded_string'
    );
    

    Now I had 2 functions. One to Parse $many_entries (jsonDecodeFieldsArray) array and one to Parse $one_entry array structure (jsonDecodeFields).

    The problem was I used jsonDecodeFieldsArray on $one_entry which made jsonDecodeFields iterate on strings.