Problem using JSON to serialize php structures
Yesterday I found an interesting quirk while working with a code base that uses json_encode() and json_decode() to serialize data moving in and out of the database.
The benifits of using JSON over standard PHP serialization (for basic objects) are fairly obvious:
- Data portability
- Easier to parse by hand (manual database updates)
- Lighter weight in general
But there is one gotcha… Consider this example:
$php_struct = array(
"key" => 5,
"another" = "data",
);
$json_string = json_encode( $php_struct );
//...
$php_struct = json_decode( $json_string );
// array? Nope, this is an object
echo gettype($php_struct);
Expected Unexpected Behavior
The problem here is that most often when using a serialization method in/out of the database, it should be hidden and abstracted into the boilerplate database interaction. The expectation is that if you put one thing in, you get the same thing out. Which is not the case when feeding these json functions associative arrays.
The Array Flag
json_decode() does provide a second parameter to tell it you want objects decoded as associative arrays, but again, this simply flips the problem on it’s head. You encode an object and when it’s decoded, you get an array back. It is still possible to put one thing in, and get a different thing out.
Solution?
The only solution I can think of is something like this…
Serialize
// $php_struct is what we're pushing and pulling from the database // Create a wrapper object $obj = new stdClass; // encode the actual data $obj->data = json_encode( $php_struct ); // Store whether or not it is an array $obj->is_array = is_array( $php_struct ); // encode for storage $obj_json = json_encode( $obj ); save( $obj_json );
Serialize
// deserialization $obj_json = retrieve(); $obj = json_decode( $obj_json ); $php_struct = json_decode( $obj->data, $obj->is_array );
@jondavidjohn The funny things you have to do in PHP to force your data into the datatype you want.
@epicserve It’s not specific to PHP… json has no “type” so any language that allows multiple types to be encoded will have the same issue.
@epicserve If there was a problem related to this specifically regarding php, it’s that it’s too easy to convert objects/arrays into json.