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

Php 浏览器返回要重新定义为特定对象的Json,php,json,casting,Php,Json,Casting,这就是我的情况 我正在使用PHP和Jquery 将对象编码为Json并发送到浏览器,然后用户对数据进行更改和更新,已传递的同一Json字符串现在返回给要解码的类 如何确保在解码Json字符串时,可以使用从新Json字符串定义的新数据重新创建对象 我是否需要重新初始化传递数据以在新对象中重新定义,或者是否有方法自动拾取该数据?自动?不,没有办法将JSON字符串映射到构造函数。不过,您可以编写自己的函数,或者在对象的构造函数中执行一些检查: function jsonToClass($string,

这就是我的情况

我正在使用PHP和Jquery

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

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


我是否需要重新初始化传递数据以在新对象中重新定义,或者是否有方法自动拾取该数据?

自动?不,没有办法将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;
        }
    }
}
然后,在对象的构造函数中:

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化,您甚至可以实现一个
\uuuuToString
魔术方法,或者一个必须手动调用的方法:

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;
顺便说一句,手动调用的方法看起来非常相似,但可能更可取:

//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的实例

最后,如果您正在考虑实现这个
格式
方法(在进一步研究之后),我是否可以建议创建一个
接口
特征
抽象类
?大致如下:

interface Formatable
{//horrid name, I know
    const FORMAT_ARRAY = 1;
    const FORMAT_OBJ = 2;
    const FROMAT_JSON = 3;
    const FORMAT_OBJ_REC = 4;

    public function format($format = self::FORMAT_ARRAY, array $exclude = array());
}
//implement for data classes
abstract class DataModels implements Formatable
{
    protected $properties = array();
    public $something = null;
    final public function format($format = self::FORMAT_ARRAY, array $exclude = array())
    {
        $return = array();
        foreach($this->set as $prop)
        {
            if (!in_array($prop, $exclude))
            {//format recursively through type-hinting!
                $return[$prop] = $this->{$prop} instanceof Formatable ?
                     $this->{$prop}->format($format, $exclude) : $this->{$prop}
            }
        }
        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);
            default:
                throw new InvalidArgumentException($format. ' is not a valid format type');
        }
    }
}
警告

这些代码都没有经过测试,我只是在这里从头开始写的,很可能包含错误。

自动?不,没有办法将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;
        }
    }
}
然后,在对象的构造函数中:

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化,您甚至可以实现一个
\uuuuToString
魔术方法,或者一个必须手动调用的方法:

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;
顺便说一句,手动调用的方法看起来非常相似,但可能更可取:

//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的实例

最后,如果您正在考虑实现这个
格式
方法(在进一步研究之后),我是否可以建议创建一个
接口
特征
抽象类
?大致如下:

interface Formatable
{//horrid name, I know
    const FORMAT_ARRAY = 1;
    const FORMAT_OBJ = 2;
    const FROMAT_JSON = 3;
    const FORMAT_OBJ_REC = 4;

    public function format($format = self::FORMAT_ARRAY, array $exclude = array());
}
//implement for data classes
abstract class DataModels implements Formatable
{
    protected $properties = array();
    public $something = null;
    final public function format($format = self::FORMAT_ARRAY, array $exclude = array())
    {
        $return = array();
        foreach($this->set as $prop)
        {
            if (!in_array($prop, $exclude))
            {//format recursively through type-hinting!
                $return[$prop] = $this->{$prop} instanceof Formatable ?
                     $this->{$prop}->format($format, $exclude) : $this->{$prop}
            }
        }
        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);
            default:
                throw new InvalidArgumentException($format. ' is not a valid format type');
        }
    }
}
警告

这些代码都没有经过测试,我只是在这里一笔勾销,很可能包含错误。

请阅读本网站的帮助中心,特别是。你有两个答案,重点是两个完全不同的东西(JS-PHP),所以你的问题可以更具体。你没有向我们展示你的努力,也没有展示你面临的任何具体问题。在看了我的答案后,我倾向于说我在回答你的问题上比你自己在研究/试图解决这个问题上付出了更多的努力。。。我写的代码比你在这里展示的要多,无论如何,请阅读本网站的帮助中心。你有两个答案,重点是两个完全不同的东西(JS-PHP),所以你的问题可以更具体。你没有向我们展示你的努力,也没有展示你面临的任何具体问题。在看了我的答案后,我倾向于说我在回答你的问题上比你自己在研究/试图解决这个问题上付出了更多的努力。。。无论如何,我写的代码比你在这里展示的要多