Как получить защищенное свойство объекта в PHP

У меня есть объект, имеющий некоторое защищенное свойство, которое я хочу получить и установить. Объект выглядит

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 ) 

Я хочу получить value свойства объекта. Когда я пытаюсь $obj->_value или $obj->value он генерирует ошибку. Я искал и нашел решение использовать PHP Reflection Class . Он работал на моем локальном, но на сервере. PHP-версия – 5.2.17 Поэтому я не могу использовать эту функцию там. Итак, какое-нибудь решение, как получить такое свойство?

Это то, на что предназначен «защищенный», поскольку главу « Видимость» объясняет:

Доступ к элементам, объявленным защищенными, может быть доступен только внутри самого класса и наследуемых и родительских классов.

Если вам нужно получить доступ к собственности извне, выберите один:

  • Не объявляйте его защищенным, сделайте его общедоступным
  • Напишите пару функций для получения и установки значения (геттеры и сеттеры)

Если вы не хотите изменять оригинальный класс (потому что это сторонняя библиотека, которую вы не хотите испортить), создайте пользовательский класс, который расширяет исходный:

 class MyFields_Form_Element_Location extends Fields_Form_Element_Location{ } 

… и добавьте там ваш приемник / сеттер.

Вот простой пример (без проверки ошибок) использования ReflectionClass :

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

Я знаю, что вы сказали, что ограничены 5.2, но это было 2 года назад, 5.5 – самая старая поддерживаемая версия, и я надеюсь помочь людям с современными версиями.

Объект может быть типизирован в (ассоциативный) массив, а защищенные члены имеют ключи с префиксом chr(0).'*'.chr(0) (см. Комментарий @ fardelian здесь ). Используя эту непризнанную функцию, вы можете написать «exposer»:

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

В качестве альтернативы вы можете проанализировать значение из сериализованной строки, где (кажется) защищенные члены имеют один и тот же префикс (надеюсь, что php 5.2 не изменил его).

Если вы не можете изменить исходный класс и расширить его, это также не вариант, вы можете использовать интерфейс ReflectionProperty.

Для этого библиотека phptoolcase имеет удобный способ:

 $value = PtcHandyMan::getProperty( $your_object , 'propertyName'); 

Статическое свойство из одноэлементного класса:

 $value = PtcHandyMan::getProperty( 'myCLassName' , 'propertyName'); 

Вы можете найти инструмент здесь: http://phptoolcase.com/guides/ptc-hm-guide.html

Если вы хотите возиться с классом, не добавляя геттеры и сеттеры ….

PHP 7 добавляет метод вызова ($ obj) (быстрее, чем старый bindTo) при закрытии, позволяющий вам вызывать функцию, поэтому переменная $this будет действовать так же, как и в классе – с полными разрешениями.

  //test class with restricted properties class test{ protected $bar="protected bar"; private $foo="private foo"; public function printProperties(){ echo $this->bar."::".$this->foo; } } $testInstance=new test(); //we can change or read the restricted properties by doing this... $change=function(){ $this->bar="I changed bar"; $this->foo="I changed foo"; }; $change->call($testInstance); $testInstance->printProperties(); //outputs I changed bar::I changed foo in php 7.0 
  $propGetter = Closure::bind( function($prop){return $this->$prop;}, $element['field_text']['#object'], $element['field_text']['#object'] ); drupal_set_message('count='.count($propGetter('hostEntity')->field_captioned_carousel['und']));