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

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

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 Поэтому я не могу использовать эту функцию там. Так какое-нибудь решение, как получить такую ​​недвижимость?

45

Решение

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

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

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

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

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

class MyFields_Form_Element_Location extends Fields_Form_Element_Location{
}

… и добавьте туда свой геттер / сеттер.

21

Другие решения

Вот действительно простой пример (без проверки ошибок), как использовать 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 самая старая поддерживаемая версия и я надеюсь помочь людям с современными версиями.

74

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

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

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

39

Если вы хотите повозиться с классом без добавления методов получения и установки ….

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
8

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

В библиотеке phptoolcase есть удобный метод для этого:

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

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

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

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

3
  $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']));
-1
По вопросам рекламы [email protected]