【问题标题】:How do I json encode private properties in php?如何在 php 中对私有属性进行 json 编码?
【发布时间】:2026-02-15 15:40:01
【问题描述】:

我正在使用学说 2 和 zend 框架 1.11。在 Doctrine 2 中不鼓励公共属性,所以我将我的实体属性设为私有。但是我刚刚了解到 Zend_Json::encode() 和 json_encode() 不会看到私有/受保护的属性,因此不会将它们添加到它们的输出中。

因此,当我使用其中一个和 var_dump 时,我得到一个空集,例如 string(4) "[{}]"。

事实证明,我必须编写自己的函数来进行编码。我希望有人有我可以使用的解决方案。

【问题讨论】:

  • 我读过同样的东西并试图解决那些私有模型属性,但最终放弃了。我的应用程序中 Doctrine 的全部要点都被 Ext.Direct API 公开,该 API 在内部使用 json_encode。使用序列化程序或打包方法来解决这个问题实在是太费劲了,特别是因为我的模型是自动生成的。我知道这是不好的做法,但它仍然非常有效。

标签: php json


【解决方案1】:

我相信 php 5.4 有 JsonSerializable 这应该会让事情变得更容易,但我使用的是 php 5.3.8。我没有尽可能多地对此进行测试,并认为我将满足于公开我的属性,但这似乎适用于我自己的课程:

class JSONEncoder{

public function json_encode($object){
    return json_encode($this->getFields($object));
}

private function getFields($classObj){
    $fields = array();
    $reflect = new ReflectionClass($classObj);
    $props   = $reflect->getProperties();
    foreach($props as $property){
        $property->setAccessible(true);
        $obj = $property->getValue($classObj);
        $name = $property->getName();
        $this->doProperty($fields, $name, $obj);
    }

    return $fields;

 }

 private function doProperty(&$fields, $name, $obj){

     if (is_object($obj)){
         $fields[$name] = $this->getFields($obj);
         return;
     }

     if (is_Array($obj)){
         $arrayFields = Array();
         foreach ($obj as $item){
             $key = key($obj);
             $this->doProperty($arrayFields, $key, $item);
             next($obj);
         }
         $fields[$name] = $arrayFields;
     }
     else 
         $fields[$name] = $obj;
 }
}

【讨论】:

    【解决方案2】:

    将成员变量设为私有的全部目的是防止它们对任何外部代码可见(序列化是一个例外,因为整个对象需要在会话之间恢复)。

    您或许应该使用“encode”方法创建一个“encodeable”接口,而不是 json_encoding 这个对象。这将返回此对象所需的任何成员的 json 编码字符串。这为您提供了额外的控制权,因为您可以选择要序列化的成员,甚至对它们执行操作以序列化其他数据,而不是序列化所有成员。

    其实你可以实现JsonSerializable接口,直接和json_encode一起工作。

    class MyClass implements \JsonSerializable
    {
        public function jsonSerialize()
        {
            return get_object_vars($this);
        }
    }
    
    $myObject = new MyClass();
    echo json_encode($myObject);
    

    【讨论】:

    • 你能举个例子吗?
    【解决方案3】:

    您可以在将对象传递给 json_encode() 之前 serialize() 您的对象

    【讨论】:

    • JavaScript 将如何反序列化它?
    • 你既没有提到 JavaScript 也没有标记这个问题 :)
    • 这不是我的问题:)。我只是好奇,因为 json_encode 通常用于对 JavaScript 使用的数据进行编码。
    【解决方案4】:

    在你的类中创建一个方法:

    function serialize(){
        return json_encode(get_object_vars ($this));
    }
    

    【讨论】: