Подтвердить что ты не робот

Обнаруживать, если свойство объекта является приватным в 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' 

Я бы хотел, чтобы он не включал "bar".

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

4b9b3361

Ответ 1

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

Ответ 2

Проверьте этот код 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";
    }
  }

Ответ 3

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

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

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

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

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

Ответ 4

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

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

Ответ 5

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

Ответ 6

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

Ответ 7

Вы можете использовать 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
}