【问题标题】:PHP making a protected property public at runtimePHP 在运行时公开受保护的属性
【发布时间】:2012-12-05 04:03:09
【问题描述】:

问题:我不想暴露$myProperty,也就是说它不应该是public,但我需要它是public,只是为了__toString()

class A
{
    protected $myProperty;

    public function __toString()
    {
        return json_encode($this);
    }
}

我知道ReflectionProperty 类有一个名为setAccessible() 的方法,但是在返回字符串之前我应该​​如何使用它?

编辑:根据 cmets,我需要与 PHP 5.3.x 兼容,即没有 JSonSerializable 类。

【问题讨论】:

  • 最好实现JsonSerializable接口,明确哪些字段会被序列化,哪些不会。
  • 我不得不说setAccessible() 可能属于“你永远不应该使用的邪恶魔法”的范畴。这很有趣,但在生产代码中绝不应该是必需的。
  • @moonwave99 当然,但我需要与 5.3.x 兼容。
  • @gremo 好吧,基本上是一样的——你不实现接口,当你需要的时候显式调用方法^^

标签: php reflection public protected


【解决方案1】:

您为什么不简单地构建一个 PHP stdClass 对象,然后将其序列化为 JSON,因为当您从 JSON 反序列化时,这正是您所得到的。

可能是这样的:

public function __toString() {
   $return = new stdClass();
   $properties = get_object_vars($this);
   foreach ($properties as $key => $value) {
       $return->$key = $value;
   }
   return json_encode($return);
}

【讨论】:

    【解决方案2】:

    根据 PHP 5.3,在 __toString() 方法中使用 get_object_vars

    public function __toString()
    {
        return json_encode(get_object_vars($this));
    }
    

    使用Demo

    class A
    {
        protected $myProperty = 'hello';
    
        public function __toString()
        {
            return json_encode(get_object_vars($this));
        }
    }
    
    echo new A; 
    

    输出:

    {"myProperty":"hello"}
    

    提示:创建您自己的JsonSerializable 接口并实现您自己的jsonSerialize() 方法以向上兼容。在需要时调用该函数和/或在 __toString() 内部调用它:

    public function __toString()
    {
        return json_encode($this->jsonSerialize());
    }
    

    【讨论】:

    • 有趣...这将起作用,因为受保护的属性在范围内,对吧?
    • 没错。也会给私有财产。与 (array) $this 一样,但它有副作用,所以 get_object_vars 更好。
    • 很好奇,(object) 有必要在这里投射吗?
    • @zerkms:技术上不是,因为json_encode 会因为非数字键而编码为 json 对象。已编辑。 (好地方,谢谢)
    猜你喜欢
    • 2011-06-06
    • 2013-10-10
    • 2016-02-19
    • 2011-03-11
    • 2020-03-31
    • 2011-10-11
    • 1970-01-01
    • 1970-01-01
    • 2012-05-17
    相关资源
    最近更新 更多