【问题标题】:How to control json_encode behavior?如何控制 json_encode 行为?
【发布时间】:2012-02-05 08:58:30
【问题描述】:

有没有办法控制json_encode 对对象的行为?比如排除空数组、空字段等?

我的意思是在使用serialize() 时,您可以实现魔术__sleep() 方法并指定应该序列化的属性:

class MyClass
{
   public $yes   = "I should be encoded/serialized!";
   public $empty = array(); // // Do not encode me!
   public $null  = null; // Do not encode me!

   public function __sleep() { return array('yes'); }
}

$obj = new MyClass();
var_dump(json_encode($obj));

【问题讨论】:

    标签: php object serialization json


    【解决方案1】:

    最正确的方案是扩展接口JsonSerializable;

    通过使用此接口,您只需要使用 jsonSerialize() 函数返回您希望 json_encode 编码的内容,而不是您的类。

    用你的例子:

    class MyClass implements JsonSerializable{
    
       public $yes   = "I should be encoded/serialized!";
       public $empty = array(); // // Do not encode me!
       public $null  = null; // Do not encode me!
    
       function jsonSerialize() {
               return Array('yes'=>$this->yes);// Encode this array instead of the current element
       }
       public function __sleep() { return array('yes'); }//this works with serialize()
    }
    
    $obj = new MyClass();
    echo json_encode($obj); //This should return {yes:"I should be encoded/serialized!"}
    

    注意:这适用于 php >= 5.4 http://php.net/manual/en/class.jsonserializable.php

    【讨论】:

    • 使用此解决方案,当“empty”和“null”的值不是空数组或空值时,将不会对其进行编码。我相信这不是提问者想要的。
    【解决方案2】:

    您可以将变量设为私有。然后它们不会出现在 JSON 编码中。

    如果这不是一个选项,您可以创建一个私有数组,并使用魔术方法 __get($key) 和 __set($key,$value) 设置和获取该数组中的值。在您的情况下,键将是“空”和“空”。然后您仍然可以公开访问它们,但 JSON 编码器不会找到它们。

    class A
    {
        public $yes = "...";
        private $privateVars = array();
        public function __get($key)
        {
            if (array_key_exists($key, $this->privateVars))
                return $this->privateVars[$key];
            return null;
        }
        public function __set($key, $value)
        {
            $this->privateVars[$key] = $value;
        }
    }
    

    http://www.php.net/manual/en/language.oop5.overloading.php#object.get

    【讨论】:

    • 是的,我知道,但感谢您的回答。问题是当B扩展A时,B无法修改$privateVars并使其变为private
    • 会使其受保护工作吗?为什么 B 要将 $privateVars 设为私有,它已经是私有的了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-17
    • 2013-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-28
    相关资源
    最近更新 更多