Intereting Posts
Загрузка php-файла 500 ошибок внутреннего сервера Необходимо заменить слова в тексте специальными синонимами Как заставить загрузку изображений в браузере? Поиск PHP ключа в многомерном массиве ajax отправить запрос на php то же значение Как получить несколько ответов из файла PHP через AJAX? Прикрепление значения текстового поля к ссылке в виде переменной без использования кнопки отправки PHP: Возможно ли создать объект SplFileObject из содержимого файла (строки)? Снятие сеансов (PHP) Сохранить данные моего файла cookie в базе данных MySQL? Связь между длиной ввода и длиной зашифрованного текста в AES Ошибка с запросом MySQL «CREATE TABLE» Как вызвать статическую дочернюю функцию из родительской статической функции? PHP Преобразование даты форматирования HTML SQLSTATE : ошибка синтаксиса или нарушение доступа: 1064 У вас есть ошибка в синтаксисе SQL – PHP – PDO

Получение статического свойства из класса с динамическим именем класса в PHP

У меня есть это:

  • одна строковая переменная, которая содержит имя класса ( $classname )
  • одна строковая переменная с именем свойства ( $propertyname )

Я хочу получить это свойство из этого класса, проблема в том, что свойство является статическим, и я не знаю, как это сделать.

Если свойство не было статическим, это было бы:

 $classname->$propertyname; 

если свойство было методом, я мог бы использовать функцию call_user_function

 call_user_func(array($classname, $propertyname)); 

Но в моем случае я просто проиграл. Однако я надеюсь, что это возможно. С тысячами функций, которые имеет PHP, у него тоже есть что-то для этого. Может, я что-то упустил?

Благодаря!

Редактировать:

  • для тех, у кого есть решения eval () : спасибо, но это не может быть и речи
  • для тех, у кого есть решения _class _vars () : спасибо, но кажется, что он возвращает «свойства по умолчанию для данного класса» (php.net), и да, я хотел бы, чтобы это значение менялось (хотя оно и помогло мне в некоторых случаях)

Если вы используете 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

Использование 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; } }