Serializing PHP Object to Json

Serializing PHP object to JSON



edit: it's currently 2016-09-24, and PHP 5.4 has been released 2012-03-01, and support has ended 2015-09-01. Still, this answer seems to gain upvotes. If you're still using PHP < 5.4, your are creating a security risk and endagering your project. If you have no compelling reasons to stay at <5.4, or even already use version >= 5.4, do not use this answer, and just use PHP>= 5.4 (or, you know, a recent one) and implement the JsonSerializable interface


You would define a function, for instance named getJsonData();, which would return either an array, stdClass object, or some other object with visible parameters rather then private/protected ones, and do a json_encode($data->getJsonData());. In essence, implement the function from 5.4, but call it by hand.

Something like this would work, as get_object_vars() is called from inside the class, having access to private/protected variables:

function getJsonData(){
$var = get_object_vars($this);
foreach ($var as &$value) {
if (is_object($value) && method_exists($value,'getJsonData')) {
$value = $value->getJsonData();
}
}
return $var;
}

Serialize/deserialize nested objects to JSON with type in PHP

I suggest you to use php's serialize function

In cases like this it's better to use this function because it exists for this purpose: you can store the serialized string wherever you want and after unserializing it you will get back the original PHP object with all the properties

With JSON, as you said, you'll have no clue of what class the object was (unless you store it manually as a string) and of course there will be all the problems related to the private properties

PHP Array Object to Serialize

If you just want json, you should only use json_encode(), not serialize().

Since your object properties are set as protected, they will however not be available when you encode the object whitout some additional help.

This is where the interface JsonSerializable comes into play.

You need to make sure that the object you want to encode implements the interface. Then you need to add a jsonSerialize() method to the class.

class Branch implements \JsonSerializable
{
protected $id;
protected $name;
protected $type;

// ... your class code

public function jsonSerialize()
{
// Return what you want to be encoded
return [
'id' => $this->id,
'name' => $this->name,
'type' => $this->type,
];
}
}

If you now pass this object through json_encode() and you'll get a json string with what our new method returns.

Serialize/unserialize PHP object-graph to JSON

The finished script (posted above) meets my precise requirements:

  • Serialize and unserialize an entire aggregate.

  • Have a JSON representation that closely resembles the original data-structure.

  • Do not pollute the data-structure with dynamically generated keys or other data.

It does not handle circular references. As pointed out in a comment above there is no right way to store circular references or multiple references to the same object, as these are all equal. Realizing this, I decided my object-graph must be a regular tree, and accepted this limitation as "a good thing".

update: the ouput can now be formatted with indentation, newlines and whitespace - it was important for me to have a human-readable (and source-control friendly) representation for my purposes. (The formatting can be enabled or disabled as needed.)

Serialize or json in PHP?

Main advantage of serialize : it's specific to PHP, which means it can represent PHP types, including instances of your own classes -- and you'll get your objects back, still instances of your classes, when unserializing your data.



Main advantage of json_encode : JSON is not specific to PHP : there are libraries to read/write it in several languages -- which means it's better if you want something that can be manipulated with another language than PHP.

A JSON string is also easier to read/write/modify by hand than a serialized one.

On the other hand, as JSON is not specific to PHP, it's not aware of the stuff that's specific to PHP -- like data-types.



As a couple of sidenotes :

  • Even if there is a small difference in speed between those two, it shouldn't matter much : you will probably not serialize/unserialize a lot of data
  • Are you sure this is the best way to store data in a database ?

    • You won't be able to do much queries on serialized strins, in a DB : you will not be able to use your data in where clauses, nor update it without the intervention of PHP...

How to serialize a PHP object into a JavaScript object (Not JSON)

Other than making the payload very slightly smaller, there's no need to do this. The output of json_encode is valid JavaScript code, if used where a value is expected, e.g.:

var x = <?php echo json_encode($array); ?>;

The quoted property keys are valid JavaScript. JSON as a whole is, in fact, a subset of JavaScript literal syntax.

You could throw a regular expression at the result. It can probably never be perfect (JSON, like HTML, can't be correctly parsed with a single regular expression), but within a limited domain you might be able to do it. For instance, here's a naive version that would probably work for many data sets, including your example, though again it would not work with all data sets by any means:

<?php
$str = json_encode($array);
$str = preg_replace('/"([A-Za-z0-9_$]+)":/', '$1:', $str);
?>
var x = <?php echo json_encode($array); ?>;

That assumes anything that consists of just A-Z, a-z, 0-9, _, or $ between double quotes followed immediately by a colon is a key and removes the quotes. (That's not a complete list of valid JavaScript identifier characters, it's just an example.)

But it seems unlikely to me that the savings are worth the bother.

To do it correctly, of course, you'd have to do your own serializer. It wouldn't be all that hard, just a recursive function that handles descending into arrays and objects. It could still use json_encode for the values.



Related Topics



Leave a reply



Submit