Обнаруживать, если свойство объекта является приватным в PHP

Я пытаюсь создать объект PHP (5), который может выполнять итерацию через свои свойства, создавая SQL-запрос, основанный только на его публичных свойствах, а не на частных.

Поскольку этот метод родительских объектов должен использоваться дочерними объектами, я не могу просто пропустить приватные свойства по имени (я не буду знать, что они представляют в дочерних объектах).

Есть ли простой способ обнаружения внутри объекта, который из его свойств является приватным?

Вот упрощенный пример того, что у меня есть до сих пор, но этот вывод включает значение $ bar:

class testClass { public $foo = 'foo'; public $fee = 'fee'; public $fum = 'fum'; private $bar = 'bar'; function makeString() { $string = ""; foreach($this as $field => $val) { $string.= " property '".$field."' = '".$val."' <br/>"; } return $string; } } $test = new testClass(); echo $test->makeString(); 

Выдает вывод:

 property 'foo' = 'foo' property 'fee' = 'fee' property 'fum' = 'fum' property 'bar' = 'bar' 

Я бы хотел, чтобы он не включал «бар».

Если есть лучший способ повторить только публичные свойства объекта, это тоже сработает.

Вы можете использовать Reflection для изучения свойств класса. Чтобы получить только общедоступные и защищенные свойства, профилируйте подходящий фильтр для метода ReflectionClass::getProperties .

Ниже приведен пример makeString использования метода makeString .

 public function makeString() { $string = ""; $reflection = new ReflectionObject($this); $properties = $reflection->getProperties(ReflectionProperty::IS_PUBLIC); foreach ($properties as $property) { $name = $property->getName(); $value = $property->getValue($this); $string .= sprintf(" property '%s' = '%s' <br/>", $name, $value); } return $string; } 

Проверьте этот код с http://php.net/manual/reflectionclass.getproperties.php#93984

  public function listProperties() { $reflect = new ReflectionObject($this); foreach ($reflect->getProperties(ReflectionProperty::IS_PUBLIC /* + ReflectionProperty::IS_PROTECTED*/) as $prop) { print $prop->getName() . "\n"; } } 

Более быстрое решение, которое я нашел:

 class Extras { public static function get_vars($obj) { return get_object_vars($obj); } } 

а затем вызовите внутри вашего testClass:

 $vars = Extras::get_vars($this); 

дополнительное чтение в PHP.net

Если вы передадите объект массиву перед его итерацией, частные и защищенные члены будут иметь специальные префиксы:

 class Test{ public $a = 1; private $b = 1; protected $c = 1; } $a = new Test(); var_dump((array) $a); 

отображает это:

 array(3) { ["a"]=> int(1) ["Testb"]=> int(1) ["*c"]=> int(1) } 

Там есть скрытые символы, которые не отображаются. Но вы можете написать код, чтобы обнаружить их. Например, регулярное выражение /\0\*\0(.*)$/ будет соответствовать защищенным ключам, а /\0.*\0(.*)$/ будет соответствовать частным. В обоих случаях первая группа захвата соответствует имени участника.

 foreach (get_class_vars(get_class($this)) .... 

Вы можете использовать массив для хранения общедоступных свойств, добавить некоторый метод-обертку и использовать массив для вставки данных в SQL.

Вы можете использовать Reflection API для проверки видимости свойств:

 $rp = new \ReflectionProperty($object,$property); if($rp->isPrivate) { // Run if the property is private } else { // Run if the property is Public or Protected }