Convert/Cast an Stdclass Object to Another Class

Convert/cast an stdClass object to another class

See the manual on Type Juggling on possible casts.

The casts allowed are:

  • (int), (integer) - cast to integer
  • (bool), (boolean) - cast to boolean
  • (float), (double), (real) - cast to float
  • (string) - cast to string
  • (array) - cast to array
  • (object) - cast to object
  • (unset) - cast to NULL (PHP 5)

You would have to write a Mapper that does the casting from stdClass to another concrete class. Shouldn't be too hard to do.

Or, if you are in a hackish mood, you could adapt the following code:

function arrayToObject(array $array, $className) {
return unserialize(sprintf(
'O:%d:"%s"%s',
strlen($className),
$className,
strstr(serialize($array), ':')
));
}

which pseudocasts an array to an object of a certain class. This works by first serializing the array and then changing the serialized data so that it represents a certain class. The result is unserialized to an instance of this class then. But like I said, it's hackish, so expect side-effects.

For object to object, the code would be

function objectToObject($instance, $className) {
return unserialize(sprintf(
'O:%d:"%s"%s',
strlen($className),
$className,
strstr(strstr(serialize($instance), '"'), ':')
));
}

How do I convert stdClass to my custom class recursively?

Maybe something like this:

foreach($object as &$prop) {
if(is_object($prop)) {
$prop = cast($prop, $class);
}
}

return unserialize(
preg_replace(
'/^O:\d+:"[^"]++"/',
'O:'.strlen($class).':"'.$class.'"',
serialize($object)
)
);

Cast object to stdClass

You have to do a double cast to do what you want...

$v = (object)(array)$v;

Convert stdClass object to array in PHP

The easiest way is to JSON-encode your object and then decode it back to an array:

$array = json_decode(json_encode($object), true);

Or if you prefer, you can traverse the object manually, too:

foreach ($object as $value) 
$array[] = $value->post_id;

How to extract information from stdClass object?

You store the data in $this->data property and also overriding all other properties of the Mailable class.

You should store the data from the database in a local variable like this:

$data = DB::select('select * from newsletter_mails order by id desc limit 1')[0];
$from = $data->from;

\Log::info(print_r($from, true));

php stdClass to array

The lazy one-liner method

You can do this in a one liner using the JSON methods if you're willing to lose a tiny bit of performance (though some have reported it being faster than iterating through the objects recursively - most likely because PHP is slow at calling functions). "But I already did this" you say. Not exactly - you used json_decode on the array, but you need to encode it with json_encode first.

Requirements

The json_encode and json_decode methods. These are automatically bundled in PHP 5.2.0 and up. If you use any older version there's also a PECL library (that said, in that case you should really update your PHP installation. Support for 5.1 stopped in 2006.)


Converting an array/stdClass -> stdClass

$stdClass = json_decode(json_encode($booking));

Converting an array/stdClass -> array

The manual specifies the second argument of json_decode as:

assoc

When TRUE, returned objects will be converted into associative arrays.

Hence the following line will convert your entire object into an array:

$array = json_decode(json_encode($booking), true);

Is there any way to convert an array to class properties?

An array is not an object. So you can't cast it with a language construct. Even casting user defined objects in PHP is not possible.

So you have to write your own logic. There are some fancy approaches by serialize() the object, change the class name and unserialize() it again to automate the process.

Also you could write a cast function using reflection. But everything needs user logic.

See also this post on SO: Type casting for user defined objects

So if you really like to cast objects I ended up with this function (see it in action):

function cast($to, $obj)
{
$toLength = strlen($to);
$serializedObj = preg_replace('/^O:\\d+:"[^"]+"/', 'O:' . $toLength . ':"' . $to . '"', serialize($obj));

$serializedObj = preg_replace_callback('/s:(\\d+):"([^"]+)";(.+?);/', function($m) use($to, $toLength) {
$propertyName = $m[2];
$propertyLength = $m[1];

if(strpos($m[2], "\0*\0") === false && ($pos = strrpos($m[2], "\0")) !== false) {
$propertyName = "\0" . $to . "\0" . substr($m[2], $pos + 1);
$propertyLength = ($m[1] + $toLength - $pos + 1);
}

return 's:' . $propertyLength . ':"' . $propertyName . '";' . $m[3] . ';';
}, $serializedObj);

return unserialize($serializedObj);
}

$user = array(
'id'=> 2,
'fname' => 'FirstName',
'lname' => 'LastName',
'username' => 'UserName'
);

$userObj = cast(User::class, (object)$user);

print_r($userObj);

But I would never ever use this function in production. It's just an experimental thing.

Update

Okay I rethought how casting is handled in Java. In Java you actually can just cast from an object to a child object of it. You can't cast from any object to any other.

So you could do this in Java:

$apple = new Apple();
$macintoshApple = (MacintoshApple)$apple;

given that MacintoshApple extends Apple.

But you can't cast two unrelated objects like:

$apple = new Apple();
$pear = (Pear)$apple;


Related Topics



Leave a reply



Submit