How to access all the properties of an object without using “reflection”

    Why get access to all the properties of an object and still not change its interface? For example, in order to write your serialization . Or to pass the object in an acceptable form using http. Or for something else.

    Let's take a simple class for the experiment.

    classaClass{
        protected $protected_property = 'protected_value';
        private $private_property = 'private_value';
        public $public_property = 'public_value';
        }
    $an_object = new aClass;
    var_dump($an_object);
    //    object(aClass)#1 (3) {//      ["protected_property":protected]=>//      string(15) "protected_value"//      ["private_property":"aClass":private]=>//      string(13) "private_value"//      ["public_property"]=>//      string(12) "public_value"//    }


    If you use "reflection", then you can get all the properties of an object, for example, in this way.

    $an_array = array();
    $reflection = new ReflectionClass($an_object);
    $properties = $reflection->getProperties();
    foreach ($properties as $property)
        {
        $property->setAccessible(true);
        $an_array[$property->getName()] = $property->getValue($an_object);
        if (!$property->isPublic())
            $property->setAccessible(false);
        }
    var_dump($an_array);
    //    array(3) {//      ["protected_property"]=>//      string(15) "protected_value"//      ["private_property"]=>//      string(13) "private_value"//      ["public_property"]=>//      string(12) "public_value"//    }


    There is an easier way to get all properties as an array.

    $an_array = (array) $an_object;
    var_dump($an_array);
    //    array(3) {//      ["�*�protected_property"]=>//      string(15) "protected_value"//      ["�aClass�private_property"]=>//      string(13) "private_value"//      ["public_property"]=>//      string(12) "public_value"//    }


    It turned out a little "dirty", if necessary, then you can clear the keys from unnecessary data. For example, like this:

    $key = ($key{0} === "\0") ? substr($key, strpos($key, "\0", 1) + 1) : $key;
    


    By the way, the reverse trick with converting the array to an object will not work. This way you can get only the stdClass object.

    $an_another_object = (object) $an_array;
    var_dump($an_another_object);
    //    object(stdClass)#6 (3) {//      ["protected_property":protected]=>//      string(15) "protected_value"//      ["private_property":"aClass":private]=>//      string(13) "private_value"//      ["public_property"]=>//      string(12) "public_value"//    }


    There is still an undocumented way to get properties. This method even looks like a bug , but it is not, therefore, it can be safely used.

    $an_array = array();
    reset($an_object);
    while (list($key, $val) = each($an_object))
        $an_array[$key] = $val;
    var_dump($an_array);
    //    array(3) {//      ["�*�protected_property"]=>//      string(15) "protected_value"//      ["�aClass�private_property"]=>//      string(13) "private_value"//      ["public_property"]=>//      string(12) "public_value"//    }


    In turn, in order to set a new value for an arbitrary property (including a private one), one can already use another undocumented trick .

    $an_array["\0aClass\0private_property"] = 'new_private_value';
    array_walk($an_object, function(&$val, $key, $array){$val = $array[$key];}, $an_array);
    var_dump($an_object);
    //    object(aClass)#1 (3) {//      ["protected_property":protected]=>//      string(15) "protected_value"//      ["private_property":"aClass":private]=>//      string(17) "new_private_value"//      ["public_property"]=>//      string(12) "public_value"//    }


    Conclusion

    Using this or that case, remember that in this way you treacherously intrude into the protected area of ​​the object, thereby bypassing all the protections that are set as protected or private, and the object will not even know anything about it. Therefore, if possible, it is better to make special access methods.

    Also popular now: