Определить, является ли свойство объекта приватным в PHP - PullRequest
21 голосов
/ 12 мая 2010

Я пытаюсь создать объект 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' 

Я бы хотел, чтобы в нем не было 'bar'.

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

Ответы [ 8 ]

18 голосов
/ 12 мая 2010

Проверьте этот код от 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";
    }
  }
12 голосов
/ 12 мая 2010

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

Вот краткий пример того, как ваш 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;
}
4 голосов
/ 20 ноября 2012

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

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

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

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

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

2 голосов
/ 12 мая 2010

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

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(.*)$/ - частным. В обоих случаях первая группа захвата соответствует имени участника.

1 голос
/ 16 октября 2018
$propertyName = 'bar';

if(in_array(propertyName, array_keys(get_class_vars(get_class($yourObject))))) {

}
1 голос
/ 12 мая 2010

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

1 голос
/ 12 мая 2010
foreach (get_class_vars(get_class($this)) ....
0 голосов
/ 16 апреля 2015

Вы можете использовать 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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...