0

I've recently ran into an issue where I had to convert an object that functions as a model (enforcing datatypes and such) into an array for further processing. At least the public and private properties have to show up.

Looking on stack overflow, I've found various methods to do so, however most only worked for single dimensions (no nested models), while the multidimensional versions always left the full model name in array keys.

How can I get this done while keeping the code clean?

Edit: Since someone marked this as duplicate, it's not. The 2 issues linked as duplicate (one that I even referred to myself) are not the same as they either don't work for multidimensional objects, or keep array keys including the class name prefixed to the property name. I've tested both of those solutions in my search, and neither did exactly what I described.

ZeroThe2nd
  • 1,652
  • 1
  • 12
  • 15

1 Answers1

1

Inspired by the given answer over here, I've changed this up a little so we don't get the name prefixes anymore, then changed it into a trait that can be use-ed inside objects. The instance then can be called with $object->toArray();. The current object is assumed to be default, but another instance can be passed instead.

When used from inside an object, all private properties will also be returned in the array.

trait Arrayable
{
    public function toArray($obj = null)
    {
        if (is_null($obj)) {
            $obj = $this;
        }
        $orig_obj = $obj;

        // We want to preserve the object name to the array
        // So we get the object name in case it is an object before we convert to an array (which we lose the object name)
        if (is_object($obj)) {
            $obj = (array)$obj;
        }

        // If obj is now an array, we do a recursion
        // If obj is not, just return the value
        if (is_array($obj)) {
            $new = [];
            //initiate the recursion
            foreach ($obj as $key => $val) {
                // Remove full class name from the key
                $key = str_replace(get_class($orig_obj), '', $key);
                // We don't want those * infront of our keys due to protected methods
                $new[$key] = self::toArray($val);
            }
        } else {
            $new = $obj;
        }

        return $new;
    }
}
ZeroThe2nd
  • 1,652
  • 1
  • 12
  • 15