浏览器返回Json重新定义为特定对象

时间:2013-11-28 12:20:28

标签: php json casting

这是我的情景,

我正在使用PHP和Jquery。

一个对象被编码为Json并发送到浏览器,然后用户对数据进行更改并进行更新,已经传递的自相同Json字符串现在被返回到要解码的类中。

如何确保在解码Json字符串时,我可以使用从新Json字符串定义的新数据重新创建对象。

我是否必须重新初始化传递要在新对象中重新定义的数据,或者是否有办法自动拾取数据?

1 个答案:

答案 0 :(得分:1)

自动?不,没有办法将JSON字符串映射到构造函数。你可以 编写自己的函数,或者在对象的构造函数中做一些检查:

function jsonToClass($string, $class)
{
    $className = $class;
    if (is_object($class)) $className = get_class($class);
    return new $className(json_decode($string));
}

然后,在对象的构造函数中:

class MyClass
{
    private $prop1 = null;
    public $prop2 = null;
    private $set = array('prop2', 'prop1');

    public function __construct(stdClass $json)
    {
        foreach($json as $prop => $val)
        {//set properties
             if (in_array($prop, $this->set)) $this->{$prop} = $val;
        }
    }
}

为了轻松地json-ify你的对象,你甚至可以实现一个__toString魔术方法,或者你必须手动调用的方法:

public function __toString()
{
    $return = array();
    foreach($this->set as $prop)
    {
        $return[$prop] = $this->{$prop};
    }
    //optionally - probably a bad idea, though
    $return['class'] = __CLASS__;
    return json_encode($return);
}

然后,在发送此类的实例时,只需执行:

return (string) $instance;
BTW,你手动调用的方法看起来非常相似,但可能更可取:

//define format constants
const FORMAT_ARRAY = 1;
const FORMAT_OBJ = 2;
const FROMAT_JSON = 3;
//some specials
const FORMAT_OBJ_REC = 4;//recursive object

public function format($format = self::FORMAT_ARRAY, array $exclude = array())
{
    $return = array();
    foreach($this->set as $prop)
    {
        if (!in_array($prop, $exclude) $return[$prop] = $this->{$prop};
    }
    //optionally - probably a bad idea, though
    if (!in_array('class', $exclude)) $return['class'] = __CLASS__;
    switch($format)
    {
        case self::FORMAT_ARRAY: return $return;
        case self::FORMAT_OBJ: return (object) $return;
        case self::FORMAT_OBJ_REC: return json_decode(json_encode($return));
        case self::FORMAT_JSON: return json_encode($return);
    }
}

等等。

注释
我不会在JSON字符串中返回类的原因仅仅是因为它是服务器端信息,客户端/前端没有业务知道发送了什么类,所以不要发送它。
FORMAT_OBJ_REC的原因仅仅是因为强制转换对象只会强制转换数组,而不是递归转换:

$foo = (object) array('foo' => array('bar' => 'foobar'));
var_dump($foo->foo);

转储数组,而:

$foo = json_decode(json_encode(array('foo'=>array('bar'=> 'foobar'))));
var_dump($foo->foo);

将转储stdClass

的实例

最后,如果您正在考虑实施此format方法(在对其进行更多处理之后),我是否可以建议您创建interfacetrait或{{1}实现这个?有点像:

abstract class

警告
这些代码都没有经过测试,我只是把它写在我的头顶,它可能包含错误。