【问题标题】: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”。

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

【问题讨论】:

    标签: php oop properties


    【解决方案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))))) {
            
            }
            

            【讨论】:

              猜你喜欢
              • 2013-10-20
              • 1970-01-01
              • 2012-07-27
              • 2013-01-03
              • 1970-01-01
              • 2017-12-11
              • 1970-01-01
              • 1970-01-01
              • 2019-03-27
              相关资源
              最近更新 更多