检测对象属性是不是在 PHP 中是私有的

Posted

技术标签:

【中文标题】检测对象属性是不是在 PHP 中是私有的【英文标题】:Detect if an object property is private in PHP检测对象属性是否在 PHP 中是私有的 【发布时间】:2011-02-18 19:10:36 【问题描述】:

我正在尝试制作一个 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”。

如果有更好的方法来遍历对象的公共属性,那么这里也可以。

【问题讨论】:

【参考方案1】:
foreach (get_class_vars(get_class($this)) ....

【讨论】:

还有反射类和魔术方法__get() 恐怕我对反射类一无所知 - 我需要做一些繁重的谷歌搜索。谢谢指点。 我过去也忽略了它,但后来我发现你可以利用它获得巨大的机会。 工具箱中的另一个工具【参考方案2】:

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

【讨论】:

【参考方案3】:

检查来自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";
    
  

【讨论】:

这正是我所需要的。谢谢你的课!【参考方案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】:

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

【讨论】:

谢谢 - 我认为 powtac 比你早了大约 30 秒,但是是的,这完全符合需要。 是的,我想太多时间花在通过整洁的文档链接做出漂亮的答案上。吸取的教训,从这里开始快速而肮脏的答案! :-)【参考方案6】:

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

class Extras

    public static function get_vars($obj)
    
        return get_object_vars($obj);
    

然后在你的 testClass 内部调用:

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

additional reading in PHP.net

【讨论】:

【参考方案7】:

您可以轻松地使用反射 API 来检查属性的可见性:

$rp = new \ReflectionProperty($object, $property);

if ($rp->isPrivate) 
  // Do if the property is private
 else 
  // Do if the property is public or protected

【讨论】:

【参考方案8】:
$propertyName = 'bar';

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


【讨论】:

以上是关于检测对象属性是不是在 PHP 中是私有的的主要内容,如果未能解决你的问题,请参考以下文章

如何理解打字稿中的“属性'名称'在'用户'类型中是私有的”

php 中__set()和__get()的具体用法

构造函数

PHP在父级中访问子级的私有属性

PHP pdo 实例作为私有静态属性

C++面向对象:成员属性的私有化