phpfunctiontypesmagic-methodsobject-to-string

Is there equivalent for __toString() method for other simple types in PHP?


_toString() is called when an object is used as string. How can I do something similar for numerical values, something like __toInt(), or __toArray(). Do such methods exist? Is there a work around? Is it a bad idea to use something like that even if there is a workaround for it?


Solution

  • There is no __toArray magic-method (just check the ones that exist here), but then, there shouldn't be, IMO.
    Though people have asked for a magic toArray method, it doesn't look like such a method will be implemented any time soon.

    Considering what objects are for, and how we use them, a toInt method wouldn't make much sense, and since all objects can be cast to an array, and can be iterated over, I see very little point in using __toArray anyway.
    To "convert" on object to an array, you can use either one of the following methods:

    $obj = new stdClass;
    $obj->foo = 'bar';
    var_dump((array) $obj);
    //or
    var_dump(json_decode(json_encode($obj), true));
    

    This can be done with both custom objects, as stdClass instances alike.
    As far as accessing them as an array, I can't see the point. Why write a slow magic method to be able to do something like:

    $bar = 'foo';
    $obj[$bar];
    

    if you can do:

    $obj->{$bar}
    

    or if you can do:

    foreach($obj as $property => $value){}
    

    Or, if you need something a tad more specific, just implement any of the Traversable interfaces.
    And for those rare cases, where you want an object to produce an array from specific properties in a very particular way, just write a method for that and call that method explicitly.

    class ComplexObject
    {
        private $secret = null;
        private $childObject = null;
        public $foo = null;
        //some methods, then:
        public function toArray()
        {//custom array representation of object
            $data = array();
            foreach($this->childObject as $property => $val)
            {
                if (!is_object($this->childObject->{$property}))
                {
                    $data[$property] = $val;
                }
            }
            $data['foo'] = $this->foo;
            return $data;
        }
        //and even:
        public function toJson()
        {
            return json_encode($this->toArray());
        }
    }
    

    Ok, you have to call these methods yourself, explicitly, but that's not that hard, really... is it?