Skip to content

Instantly share code, notes, and snippets.

@bubba-h57
Created September 13, 2012 14:49
Show Gist options
  • Save bubba-h57/3714787 to your computer and use it in GitHub Desktop.
Save bubba-h57/3714787 to your computer and use it in GitHub Desktop.
Doctrine 2 Entities Serialized to JSON
<?php
namespace H57\Util;
class Serializor {
/**
* Converts the Doctrine Entity into a JSON Representation
*
* @param object $object The Object (Typically a Doctrine Entity) to convert to an array
* @param integer $depth The Depth of the object graph to pursue
* @param array $whitelist List of entity=>array(parameters) to convert
* @param array $blacklist List of entity=>array(parameters) to skip
* @return string
*/
public static function json_encode($object, $depth=1, $whitelist=array(), $blacklist=array()){
return json_encode(Serializor::toArray($object, $depth, $whitelist, $blacklist));
}
/**
* Serializes our Doctrine Entities
*
* This is the primary entry point, because it assists with handling collections
* as the primary Object
*
* @param object $object The Object (Typically a Doctrine Entity) to convert to an array
* @param integer $depth The Depth of the object graph to pursue
* @param array $whitelist List of entity=>array(parameters) to convert
* @param array $blacklist List of entity=>array(parameters) to skip
* @return NULL|Array
*
*/
public static function toArray($object, $depth = 1,$whitelist=array(), $blacklist=array()){
// If we drop below depth 0, just return NULL
if ($depth < 0){
return NULL;
}
// If this is an array, we need to loop through the values
if (is_array($object)){
// Somthing to Hold Return Values
$anArray = array();
// The Loop
foreach ($object as $value){
// Store the results
$anArray[] = Serializor::arrayizor($value, $depth, $whitelist, $blacklist);
}
// Return it
return $anArray;
}else{
// Just return it
return Serializor::arrayizor($object, $depth, $whitelist, $blacklist);
}
}
/**
* This does all the heavy lifting of actually converting to an array
*
* @param object $object The Object (Typically a Doctrine Entity) to convert to an array
* @param integer $depth The Depth of the object graph to pursue
* @param array $whitelist List of entity=>array(parameters) to convert
* @param array $blacklist List of entity=>array(parameters) to skip
* @return NULL|Array
*/
private static function arrayizor($anObject, $depth, $whitelist=array(), $blacklist=array()){
// Determine the next depth to use
$nextDepth = $depth - 1;
// Lets get our Class Name
// @TODO: Making some assumptions that only objects get passed in, need error checking
$clazzName = get_class($anObject);
// Now get our reflection class for this class name
$reflectionClass = new \ReflectionClass($clazzName);
// Then grap the class properites
$clazzProps = $reflectionClass->getProperties();
if (is_a($anObject, 'Doctrine\ORM\Proxy\Proxy')){
$parent = $reflectionClass->getParentClass();
$clazzName = $parent->getName();
$clazzProps = $parent->getProperties();
}
// A new array to hold things for us
$anArray = array();
// Lets loop through those class properties now
foreach ($clazzProps as $prop){
// If a Whitelist exists
if (@count($whitelist[$clazzName]) > 0){
// And this class property is not in it
if (! @in_array($prop->name, $whitelist[$clazzName])){
// lets skip it.
continue;
}
// Otherwise, if a blacklist exists
}elseif (@count($blacklist[$clazzName] > 0)){
// And this class property is in it
if (@in_array($prop->name, $blacklist[$clazzName])){
// lets skip it.
continue;
}
}
// We know the property, lets craft a getProperty method
$method_name = 'get' . ucfirst($prop->name) ;
// And check to see that it exists for this object
if (! method_exists($anObject, $method_name)){
continue;
}
// It did, so lets call it!
$aValue = $anObject->$method_name();
// If it is an object, we need to handle that
if (is_object($aValue)){
// If it is a datetime, lets make it a string
if (get_class($aValue) === 'DateTime'){
$anArray[$prop->name] = $aValue->format('Y-m-d H:i:s');
// If it is a Doctrine Collection, we need to loop through it
}elseif(get_class($aValue) ==='Doctrine\ORM\PersistentCollection'){
$collect = array();
foreach ($aValue as $val){
$collect[] = Serializor::toArray($val, $nextDepth, $whitelist, $blacklist);
}
$anArray[$prop->name] = $collect;
// Otherwise, we can simply make it an array
}else{
$anArray[$prop->name] = Serializor::toArray($aValue, $nextDepth, $whitelist, $blacklist);
}
// Otherwise, we just use the base value
}else{
$anArray[$prop->name] = $val;
}
}
// All done, send it back!
return $anArray;
}
}
?>
@bubba-h57
Copy link
Author

use H57\Util\Registry as Reg;

$anEntity = Reg::getRepo('Company')->find(1);

$whitelist = array(
'H57\Entity\Company' => array('id', 'name', 'trade', 'address1', 'address2', 'state', 'users', 'groups'),
'H57\Entity\User' => array('id', 'username', 'firstName', 'lastName')
);
print_r(Serializor::toArray($anEntity, 2, $whitelist));

$blacklist = array(
'H57\Entity\Company' => array('address1', 'address2'),
'H57\Entity\User' => array('password', 'lastName')
);

print_r(Serializor::toArray($anEntity, 2, NULL, $blacklist));

exit();

@tschig
Copy link

tschig commented Feb 22, 2013

Line 138: "$anArray[$prop->name] = $val;" must be "$anArray[$prop->name] = $aValuel;" I think

@ggarbereder
Copy link

Line 109:
$method_name = 'get' . preg_replace_callback(
'/_[a-zA-Z]/',
function ($match) {
$s = $match[0];
return strtoupper($s[1]);
},
ucfirst($prop->name));

Replace underscores with next letter uppercase to match naming conventions.

@Golgorz
Copy link

Golgorz commented Oct 6, 2015

If you pass a persistent collection this will throw warnings...i added a check so it works fine, its in line 41
if (is_array($object) || is_a($object, 'Doctrine\ORM\PersistentCollection')){

@ScorpioT1000
Copy link

Now you can also use https://github.com/Indaxia/doctrine-orm-transformations to convert entities to scalar arrays and back

@mrself
Copy link

mrself commented Apr 3, 2018

$val in https://gist.github.com/bubba-h57/3714787#file-serializor-php-L138 is undefined. It should be $aValue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment