Skip to content

Instantly share code, notes, and snippets.

Created May 7, 2011 00:02
  • Star 20 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
PHP function to cast an object from one class to another.
* Cast an object into a different class.
* Currently this only supports casting DOWN the inheritance chain,
* that is, an object may only be cast into a class if that class
* is a descendant of the object's current class.
* This is mostly to avoid potentially losing data by casting across
* incompatable classes.
* @param object $object The object to cast.
* @param string $class The class to cast the object into.
* @return object
function cast($object, $class) {
if( !is_object($object) )
throw new InvalidArgumentException('$object must be an object.');
if( !is_string($class) )
throw new InvalidArgumentException('$class must be a string.');
if( !class_exists($class) )
throw new InvalidArgumentException(sprintf('Unknown class: %s.', $class));
if( !is_subclass_of($class, get_class($object)) )
throw new InvalidArgumentException(sprintf(
'%s is not a descendant of $object class: %s.',
$class, get_class($object)
* This is a beautifully ugly hack.
* First, we serialize our object, which turns it into a string, allowing
* us to muck about with it using standard string manipulation methods.
* Then, we use preg_replace to change it's defined type to the class
* we're casting it to, and then serialize the string back into an
* object.
return unserialize(
Copy link

jpuck commented Nov 16, 2016

If you stick this inside a namespaced class as a method, then don't forget that the fully qualified class name won't be resolved by the alias, so you might want to do some sort of additional check for that before throwing an exception.

if( !class_exists($class) ){
    $class = __NAMESPACE__ . "\\$class";
if( !class_exists($class) )
    throw new InvalidArgumentException(sprintf('Unknown class: %s.', $class));

Copy link

To initialize properties on the new object that didn't exist in the old one (if the new extends the old), its class definition needs to have a __wakeup() method as unserialize doesn't call __construct().

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