Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get protected property of object in PHP

I have a object having some protected property that I want to get and set. The object looks like

Fields_Form_Element_Location Object ( [helper] => formText [_allowEmpty:protected] => 1 [_autoInsertNotEmptyValidator:protected] => 1 [_belongsTo:protected] =>    [_description:protected] =>  [_disableLoadDefaultDecorators:protected] =>  [_errorMessages:protected] => Array     (     )  [_errors:protected] => Array     (     ) [_isErrorForced:protected] =>  [_label:protected] => Current City   [_value:protected] => 93399 [class] => field_container field_19 option_1 parent_1 ) 

I want to get value property of the object. When I try $obj->_value or $obj->value it generates error. I searched and found the solution to use PHP Reflection Class. It worked on my local but on server PHP version is 5.2.17 So I cannot use this function there. So any solution how to get such property?

like image 227
Awais Qarni Avatar asked Dec 02 '13 17:12

Awais Qarni


People also ask

How can I access protected variable in PHP?

We can use bind() or bindTo methods of Closure class to access private/protected data of some class, for example: class MyClass { protected $variable = 'I am protected variable!

How do you access the properties of an object in PHP?

Within class methods non-static properties may be accessed by using -> (Object Operator): $this->property (where property is the name of the property). Static properties are accessed by using the :: (Double Colon): self::$property .

How can we access private members of a class in PHP?

We can use the private access modifier for class variables and methods but not for PHP class. When a class member - a variable or a function, is declared as private then it cannot be accessed directly using the object of the class. For example: <?

What is object properties PHP?

Properties of Object Properties are variables that are defined within a class. These variables are then used by the methods, objects of the class. These variables can be public, protected or private. By default, the public is used.


2 Answers

Here's the really simple example (with no error checking) of how to use ReflectionClass:

function accessProtected($obj, $prop) {   $reflection = new ReflectionClass($obj);   $property = $reflection->getProperty($prop);   $property->setAccessible(true);   return $property->getValue($obj); } 

I know you said you were limited to 5.2, but that was 2 years ago, 5.5 is the oldest supported version and I'm hoping to help people with modern versions.

like image 173
drewish Avatar answered Sep 28 '22 03:09

drewish


Object can be typecasted into (associative) array and the protected members have keys prefixed with chr(0).'*'.chr(0) (see @fardelian's comment here). Using this undocummented feature you can write an "exposer":

function getProtectedValue($obj, $name) {   $array = (array)$obj;   $prefix = chr(0).'*'.chr(0);   return $array[$prefix.$name]; } 

Alternatively, you can parse the value from serialized string, where (it seems) protected members have the same prefix.

This works in PHP 5.2 without the overhead of ReflectionClass. However, there are reasons why some property is protected and hidden from client code. The reading or writing can make the data inconsistent or the author provides some other way to expose it in effort to make the interface as lean as possible. When there are reasons to read the protected property directly, the then-correct approach was to implement __get() magic method, so always check if there is any and see what it does. This counter intuitive lookup was finally solved in PHP 8.1 with readonly properties.

Since PHP 8.0, there also attributes metadata accessible by ReflectionClass, make sure to check them also before performing attempts to break into protected members. Attributes superseded "Annotations"1, so check them, too.

1: annotations are a very nasty surprise to client coders: they parse comments to add crazy fancy black-box useless confusing functionality, should not be used anymore, but they still exist

like image 30
Jan Turoň Avatar answered Sep 28 '22 01:09

Jan Turoň