У меня есть объект, имеющий некоторое защищенное свойство, которое я хочу получить и установить. Объект выглядит
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']));