Как программно найти открытые свойства класса внутри одного из его методов
У меня есть класс Foo
с общедоступными и защищенными свойствами. Foo
должен иметь нестатический метод getPublicVars()
, который возвращает список всех общедоступных свойств Foo
(это просто пример, который я знаю извне объекта Foo
, вызывающего get_object_vars()
выполнит это, и мне не нужен мой метод getPublicVars()
).
Примечание.. Это также должно возвращать динамически объявленные свойства, назначенные во время выполнения, экземпляру класса (объекту), которые не определены в определении класса.
Вот пример:
class Foo{
private $bar = '123';
protect $boo = '456';
public $beer = 'yum';
//will return an array or comma seperated list
public function getPublicVars(){
// thar' be magic here...
}
}
$foo = new Foo();
$foo->tricky = 'dynamically added var';
$result = $foo->getPublicVars();
var_dump($result); // array or comma list with 'tricky' and 'beer'
Каков наиболее сжатый способ получить только общедоступные свойства объекта изнутри собственного метода класса, в котором видны как общедоступные, так и защищенные?
Я посмотрел:
Но это не похоже на мой вопрос, поскольку он указывает на использование get_object_vars()
вне объекта.
Ответы
Ответ 1
Как вы уже поняли, PHP-сборка get_object_vars
зависит от области. Вы хотите только свойства объекта public.
Итак, эта функция для публичного варианта не является большим шагом:
function get_object_public_vars($object) {
return get_object_vars($object);
}
Вызов этого get_object_public_vars
даст вам только общедоступные свойства, потому что он выходит за пределы текущего объекта.
Если вам нужен более мелкозернистый элемент управления, вы также можете использовать ReflectionObject
:
(new ReflectionObject($this))->getProperties(ReflectionProperty::IS_PUBLIC);
Что имеет то преимущество, что вам не нужно вводить другую функцию в глобальном пространстве имен.
Ответ 2
Не работает с версией php >= 7
Таким образом, я больше не могу рекомендовать решение.
Вместо этого используйте отражение
Чтобы получить общедоступные свойства внутри класса
$publicProperties = call_user_func('get_object_vars', $this);
"трюк" заключается в том, что get_object_vars
вызывается из области call_user_func
, а не сфера действия объекта
нет необходимости в отражении, автономных функциях, замыканиях и т.д.
Ответ 3
В соответствии с этой статьей (написанной Вэнсом Лукасом) вы можете создать новую область вызова внутри определения класса Foo, используя "анонимной" функции, а затем вы можете вызвать get_object_vars()
изнутри. Это позволит вам получить только общедоступные свойства внутри вашего класса, даже если они были созданы динамически позже извне.
Таким образом, для вашего примера это будет:
<?php
class Foo {
private $bar = '123';
protected $boo = '456';
public $beer = 'yum';
// return an array of public properties
public function getPublicVars(){
$publicVars = create_function('$obj', 'return get_object_vars($obj);');
return $publicVars($this);
}
}
$foo = new Foo();
$foo->tricky = 'dynamically added var';
$result = $foo->getPublicVars();
print_r($result);
и вывод будет:
Array
(
[beer] => yum
[tricky] => dynamically added var
)
В упомянутой выше статье есть второй пример, который показывает другой способ сделать то же самое с использованием так называемых "замыканий" (от php 5.3), но по какой-то причине он не работает для меня с php v5.4 поэтому частные и защищенные свойства остаются включенными в результирующий массив.