检测PHP中的对象属性是否为私有属性

时间:2010-05-12 19:05:26

标签: php oop properties

我正在尝试创建一个可以遍历其属性的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 个答案:

答案 0 :(得分:18)

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";
    }
  }

答案 1 :(得分:12)

您可以使用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 :(得分:4)

我找到了一个更快的解决方案:

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

然后调用testClass:

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

additional reading in PHP.net

答案 3 :(得分:2)

如果在迭代之前将对象强制转换为数组,则私有成员和受保护成员将具有特殊前缀:

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(.*)$/将匹配私有密钥。在两者中,第一个捕获组与成员名称匹配。

答案 4 :(得分:1)

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

答案 5 :(得分:1)

您可以使用数组存储公共属性,添加一些包装器方法并使用数组将数据插入SQL。

答案 6 :(得分:1)

$propertyName = 'bar';

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

}

答案 7 :(得分:0)

您可以使用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
}