Jak uzyskać chronioną właściwość obiektu w PHP
Mam obiekt posiadający jakąś chronioną własność, którą chcę zdobyć i ustawić. Obiekt wygląda jak
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
)
Chcę uzyskać value
właściwość obiektu. Kiedy próbuję $obj->_value
lub $obj->value
generuje błąd. Szukałem i znalazłem rozwiązanie do użycia PHP Reflection Class
. Działa na moim lokalnym, ale na serwerze wersja PHP jest 5.2.17
, więc nie mogę tam korzystać z tej funkcji. Więc jakieś rozwiązanie, jak uzyskać taką nieruchomość?
6 answers
Po to jest "chronione" , jak wyjaśnia Rozdział Visibility :
Członkowie zadeklarowani jako protected mogą być dostępni tylko wewnątrz samej klasy oraz przez klasy dziedziczone i nadrzędne.
Jeśli chcesz uzyskać dostęp do nieruchomości z zewnątrz, wybierz jedną z nich:
- nie deklaruj jej jako chronionej, zamiast tego upublicznij ją
- napisz kilka funkcji do get i ustaw wartość (getters i setters)
Jeśli nie chcesz zmodyfikuj oryginalną klasę (ponieważ jest to biblioteka innej firmy, której nie chcesz bałagan) Utwórz klasę niestandardową, która rozszerza oryginalną:
class MyFields_Form_Element_Location extends Fields_Form_Element_Location{
}
... i dodaj tam swój getter / setter.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-02 17:57:17
Oto bardzo prosty przykład (bez sprawdzania błędów) jak używać ReflectionClass
:
function accessProtected($obj, $prop) {
$reflection = new ReflectionClass($obj);
$property = $reflection->getProperty($prop);
$property->setAccessible(true);
return $property->getValue($obj);
}
Wiem, że mówiłeś, że ograniczyłeś się do 5.2, ale to było 2 lata temu, 5.5 jest najstarszą obsługiwaną wersją i mam nadzieję pomóc ludziom z nowoczesnymi wersjami.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-10 14:01:23
Obiekt może być wpisany do tablicy asocjacyjnej, a chronione elementy mają klucze prefiksowe chr(0).'*'.chr(0)
(Zobacz komentarz @fardelian tutaj). Korzystając z tej nieudokumentowanej funkcji można napisać "exposer":
function getProtectedValue($obj,$name) {
$array = (array)$obj;
$prefix = chr(0).'*'.chr(0);
return $array[$prefix.$name];
}
Alternatywnie, możesz przetworzyć wartość z serialized string, gdzie (jak się wydaje) protected members mają ten sam prefiks(mam nadzieję, że php 5.2 tego nie zmieniło).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-03 11:09:55
Jeśli chcesz majstrować z klasą bez dodawania getterów i setterów....
PHP 7 dodaje metodę call ($obj) (szybszą niż stare bindTo) na closures pozwalającą na wywołanie funkcji, dzięki czemu zmienna $this
będzie działać tak, jak w klasie-z pełnymi uprawnieniami.
//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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-05 04:13:55
Jeśli nie możesz zmodyfikować oryginalnej klasy, a jej rozszerzenie również nie jest opcją, możesz użyć interfejsu ReflectionProperty.
Biblioteka phptoolcase ma do tego przydatną metodę:
$value = PtcHandyMan::getProperty( $your_object , ‘propertyName’);
Własność statyczna z klasy singleton:
$value = PtcHandyMan::getProperty( ‘myCLassName’ , ‘propertyName’);
Narzędzie znajdziesz tutaj: http://phptoolcase.com/guides/ptc-hm-guide.html
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-09 07:38:22
$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']));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-08 14:03:50