У меня есть это:
$classname
) $propertyname
) Я хочу получить это свойство из этого класса, проблема в том, что свойство является статическим, и я не знаю, как это сделать.
Если свойство не было статическим, это было бы:
$classname->$propertyname;
если свойство было методом, я мог бы использовать функцию call_user_function
call_user_func(array($classname, $propertyname));
Но в моем случае я просто проиграл. Однако я надеюсь, что это возможно. С тысячами функций, которые имеет PHP, у него тоже есть что-то для этого. Может, я что-то упустил?
Благодаря!
Редактировать:
Если вы используете PHP 5.3.0 или новее, вы можете использовать следующее:
$classname::$$propertyname;
К сожалению, если вы используете версию ниже 5.3.0, вы застряли с использованием eval()
( get_class_vars()
не будет работать, если значение будет динамическим).
$value = eval($classname.'::$'.$propertyname.';');
EDIT: Я только что сказал, что get_class_vars()
не будет работать, если значение является динамическим, но, видимо, переменные статические члены являются частью «свойств по умолчанию для класса» . Вы можете использовать следующую оболочку:
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
К сожалению, если вы хотите установить значение переменной, вам все равно придется использовать eval()
, но с некоторой проверкой на месте это не так уж плохо .
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()
с этой проверкой должен быть безопасным. Если люди начинают ставить случайные вещи как $className
и $property
, они выйдут из функции, поскольку это не будет существующий класс или свойство. Начиная с $value
, он никогда не анализируется как код, поэтому все, что они там помещают, не повлияет на скрипт.
Я думаю, что это самое простое:
$foo = new ReflectionProperty('myClassName', 'myPropertyName'); print $foo->getValue();
Чтобы вернуть значение переменной, заданное переменной Static, вам необходимо вызвать:
$static_value = constant($classname.'::'.$propertyname);
Ознакомьтесь с документацией :: Постоянная документация PHP
Одна вещь, которую я заметил, это то, что вы не можете устанавливать переменные, которые защищены в статических классах, поскольку команда eval () запускается в области вне класса. Единственное, что можно обойти, это реализовать статический метод внутри / каждого класса, который запускает eval (). Этот метод можно защитить, поскольку вызов call_user_func () [для вызова метода setter] также выполняется изнутри класса.
Вы должны иметь возможность сделать что-то вроде:
eval("echo $classname::$propertyname;");
Я просто сделал быстрый тест и заставил это работать для меня. Не уверен, есть ли лучший способ или нет, но я не смог его найти.
«eval» выглядит так близко к «злу», и я ненавижу использовать его и / или видеть его в коде. С несколькими идеями из других ответов, вот способ избежать этого, даже если ваш php не 5.3 или выше.
Изменено для отражения тестирования на основе комментария.
class A { static $foo = 'bar'; } A::$foo = 'baz'; $a = new A; $class = get_class($a); $vars = get_class_vars($class); echo $vars['foo'];
Выходы «baz».
Потенциально актуально: обсуждение поздней статической привязки в PHP. Когда вам понадобится использовать позднюю статическую привязку? ,
get_class_vars
не такой же, как get_object_vars
.
Я думаю, что get_clas_vars
должен возвращать исходные значения свойств.
Даже если для вас сказал, что eval
может быть и речи, предыдущий PHP 5.3, самое простое решение по-прежнему использует eval
:
eval("\$propertyval = $classname::\$propertyname;"); echo $propertyval;
Вы можете использовать ReflectionClass:
class foo { private static $bar = "something"; } $class = "foo"; $reflector = new ReflectionClass($class); $static_vars = $reflector->getStaticProperties(); var_dump($static_vars["bar"]);
Использование Reflection работает, но это дорого
Вот что я использую для этой цели,
Он работает для PHP 5 >= 5.1.0
потому что я использую 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; } }