如何从其中一个方法中以编程方式查找类的公共属性

时间:2012-10-29 14:55:08

标签: php oop reflection

我有一个包含公共和受保护属性的类FooFoo需要有一个非静态方法getPublicVars(),它返回Foo所有公共属性的列表(这只是一个例子,我从外面知道调用get_object_vars()Foo对象将完成此操作,并且不需要我的getPublicVars()方法。

  

注意:这还必须将在运行时分配的动态声明的属性返回给类的定义中未定义的类实例(对象)。

以下是示例:

class Foo{
    private $bar = '123';
    protect $boo = '456';
    public   $beer = 'yum';

   //will return an array or comma seperated list
   public function getPublicVars(){
      // thar' be magic here...
   } 
}

 $foo = new Foo();
 $foo->tricky = 'dynamically added var';

 $result = $foo->getPublicVars();  
 var_dump($result); // array or comma list with 'tricky' and 'beer'   

从类本身的方法中获取对象的唯一公共属性的最简洁方法是什么?public和protected都可见?

我看过:

但这似乎并没有解决我的问题,因为它指的是从对象外部使用get_object_vars()

3 个答案:

答案 0 :(得分:20)

正如您已经意识到的那样,PHP在get_object_vars中的构建是对范围敏感的。您只需要 public 对象属性。

因此从该功能到公共变体不是一大步:

function get_object_public_vars($object) {
    return get_object_vars($object);
}

调用此get_object_public_vars只会为您提供公共属性,因为它超出了当前对象的范围。

如果您需要更细粒度的控制,您还可以使用ReflectionObject

(new ReflectionObject($this))->getProperties(ReflectionProperty::IS_PUBLIC);

这样做的好处是您不需要在全局命名空间中引入另一个函数。

答案 1 :(得分:15)

  

不适用于php版本> = 7
  因此,我不能再推荐解决方案。
  改为使用反射

从类中获取公共属性

$publicProperties = call_user_func('get_object_vars', $this);

“技巧”是从get_object_vars的范围调用call_user_func而不是对象的范围

不需要反射,独立功能,闭包等

答案 2 :(得分:-2)

根据this article(由Vance Lucas编写),您可以使用“ anonymous ”函数在“Foo”类定义中创建一个新的调用范围,然后您可以调用内部get_object_vars()。这样,您就可以从类中获取公共属性,即使这些属性是从外部动态创建的。

如此适应你的例子:

<?php
class Foo {
    private $bar = '123';
    protected $boo = '456';
    public   $beer = 'yum';

   // return an array of public properties 
   public function getPublicVars(){
      $publicVars = create_function('$obj', 'return get_object_vars($obj);');
        return $publicVars($this);
   } 
}

 $foo = new Foo();
 $foo->tricky = 'dynamically added var';

 $result = $foo->getPublicVars();  
 print_r($result);

,输出结果为:

Array
(
    [beer] => yum
    [tricky] => dynamically added var
)

上面提到的文章中有第二个例子显示了使用所谓的“闭包”(来自php 5.3)做同样的另一种方法,但由于某些原因它对我使用php v5.4不起作用所以私有和受保护的属性仍然包含在结果数组中。