Uzyskiwanie właściwości statycznych z klasy o dynamicznej nazwie klasy w PHP
Mam to:
- jedna zmienna łańcuchowa, która przechowuje nazwę klasy (
$classname
) - jedna zmienna łańcuchowa z nazwą właściwości (
$propertyname
)
Chcę dostać tę właściwość z tej klasy, problem w tym, że właściwość jest statyczna i nie wiem jak to zrobić.
Gdyby nieruchomość nie była statyczna, to byłoby:
$classname->$propertyname;
Gdyby właściwość była metodą, mógłbym użyć call_user_function
call_user_func(array($classname, $propertyname));
Ale w moim przypadku, jestem po prostu zagubiony. Jestem jednak mając nadzieję, że jest to możliwe. Z tysiącami funkcji, które posiada PHP, lepiej, żeby miał coś do tego. Może coś przeoczyłem?
Dzięki!
Edit:
- dla osób z rozwiązaniami eval () : Dzięki, ale to nie wchodzi w grę
- dla tych z get _class _vars () solutions: thanks, but it seems it returns "the default properties of the given class" (php.net), i tak, chciałbym, aby ta wartość była zmienny (mimo, że pomaga mi w niektórych przypadkach)
11 answers
Jeśli używasz PHP w wersji 5.3.0 lub nowszej, możesz użyć:
$classname::$$propertyname;
Niestety, jeśli używasz wersji niższej niż 5.3.0, utknąłeś przy użyciu eval()
(get_class_vars()
nie będzie działać, jeśli wartość jest dynamiczna).
$value = eval($classname.'::$'.$propertyname.';');
EDIT: właśnie powiedziałem get_class_vars()
nie działa, jeśli wartość jest dynamiczna, ale widocznie statyczne pręty zmiennych są częścią "domyślnych właściwości klasy" . Możesz użyć następującego wrappera:
function get_user_prop($className, $property) {
if(!class_exists($className)) return null;
if(!property_exists($className, $property)) return null;
$vars = get_class_vars($className);
return $vars[$property];
}
class Foo { static $bar = 'Fizz'; }
echo get_user_prop('Foo', 'bar'); // echoes Fizz
Foo::$bar = 'Buzz';
echo get_user_prop('Foo', 'bar'); // echoes Buzz
Niestety, jeśli chcesz ustawić wartość zmiennej, nadal będziesz musiał użyć eval()
, ale z pewną walidacją w miejscu, to nie jest tak złe .
function set_user_prop($className, $property,$value) {
if(!class_exists($className)) return false;
if(!property_exists($className, $property)) return false;
/* Since I cannot trust the value of $value
* I am putting it in single quotes (I don't
* want its value to be evaled. Now it will
* just be parsed as a variable reference).
*/
eval($className.'::$'.$property.'=$value;');
return true;
}
class Foo { static $bar = 'Fizz'; }
echo get_user_prop('Foo', 'bar'); // echoes Fizz
set_user_prop('Foo', 'bar', 'Buzz');
echo get_user_prop('Foo', 'bar'); // echoes Buzz
set_user_prop()
z tą walidacją powinno być bezpieczne. Jeśli ludzie zaczną umieszczać losowe rzeczy jako $className
i $property
, zakończy się to z funkcji, ponieważ nie będzie to istniejąca klasa lub właściwość. Od $value
, nigdy nie jest faktycznie parsowany jako kod tak cokolwiek tam wrzucą, nie wpłynie na scenariusz.
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
2009-08-14 18:15:18
Myślę, że to najprostsze:
$foo = new ReflectionProperty('myClassName', 'myPropertyName');
print $foo->getValue();
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
2010-02-17 12:12:03
Aby zwrócić wartość zmiennej ustawioną przez zmienną statyczną należy wywołać:
$static_value = constant($classname.'::'.$propertyname);
Sprawdź dokumentację:: PHP stała dokumentacja
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
2011-10-27 05:31:02
'eval' wygląda tak blisko 'zła', i nienawidzę go używać i / lub widzieć w kodzie. Z kilkoma pomysłami z innych odpowiedzi, oto sposób, aby go uniknąć, nawet jeśli twój php nie jest 5.3 lub wyższy.
Zmieniono, aby odzwierciedlić testy na podstawie komentarza.
class A {
static $foo = 'bar';
}
A::$foo = 'baz';
$a = new A;
$class = get_class($a);
$vars = get_class_vars($class);
echo $vars['foo'];
Wyjścia "baz".
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
2009-08-14 17:43:05
Jedną rzeczą, którą zauważyłem jest to, że nie można ustawić zmiennych, które są chronione w klasach statycznych, ponieważ polecenie eval() działa w zakresie poza klasą. Jedyną rzeczą do obejścia tego byłoby zaimplementowanie statycznej metody wewnątrz klasy / every, która uruchamia EVAL (). Ta metoda może być chroniona, ponieważ call_user_func () [aby wywołać metodę setter] działa również z wewnątrz klasy.
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
2010-02-01 17:38:11
Powinieneś być w stanie zrobić coś takiego:
eval("echo $classname::$propertyname;");
Zrobiłem szybki test i to mi się udało. Nie wiem, czy jest lepszy sposób, ale nie mogłem go znaleźć.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
2009-08-14 17:29:35
Potencjalnie istotne: dyskusja na temat późnego wiązania statycznego w PHP - Kiedy należy użyć późnego wiązania statycznego?.
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-05-23 12:00:17
get_class_vars
to nie to samo co get_object_vars
.
Myślę, że get_clas_vars
powinien zwrócić oryginalne wartości właściwości.
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
2011-11-09 19:25:39
Nawet jeśli dla Ciebie {[1] } nie wchodzi w grę, wcześniejsze PHP 5.3 najprostszym rozwiązaniem jest użycie eval
:
eval("\$propertyval = $classname::\$propertyname;");
echo $propertyval;
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
2012-01-23 20:37:16
Możesz użyć ReflectionClass:
class foo
{
private static $bar = "something";
}
$class = "foo";
$reflector = new ReflectionClass($class);
$static_vars = $reflector->getStaticProperties();
var_dump($static_vars["bar"]);
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-04-09 14:00:29
Uzyskiwanie i ustawianie właściwości statycznych i niestatycznych bez użycia odbicia
Używanie odbicia działa, ale jest kosztowne
Oto, co używam do tego celu,
Działa na PHP 5 >= 5.1.0
ponieważ używam property_exist
function getObjectProperty($object, $property)
{
if (property_exists(get_class($object), $property)) {
return array_key_exists($property, get_object_vars($object))
? $object->{$property}
: $object::$$property;
}
}
function setObjectProperty($object, $property, $value)
{
if (property_exists(get_class($object), $property)) {
array_key_exists($property, get_object_vars($object))
? $object->{$property} = $value
: $object::$$property = $value;
}
}
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
2012-08-24 04:18:08