2013-11-28 97 views
1

這是我的場景,瀏覽器返回Json被重新定義爲特定對象

我正在使用PHP和Jquery。

對象被編碼爲Json併發送到瀏覽器,然後用戶對數據進行更改並更新,已傳遞的自己相同的Json字符串現在正被返回到需要解碼的類。

如何確保在解碼Json字符串時,可以使用從新的Json字符串定義的新數據重新創建對象。

我是否需要重新初始化傳遞數據以便在新對象中重新定義或者是否有自動獲取數據的方法?

+0

請詳細閱讀本網站的幫助中心[如何提出一個好問題](http://stackoverflow.com/help/how-to-ask)。你有2個答案,關注2個完全不同的東西(JS <=> PHP),所以你的問題可能更具體。您沒有向我們展示您的任何努力,也沒有您遇到的任何具體問題。看完我的回答後,我傾向於說,我已經付出了更多的努力來回答你的問題,而不是你自己研究/試圖解決這個問題......我寫了比你在這裏顯示的更多的代碼無論如何 –

回答

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); 
} 

的D,那麼,發送此類的一個實例時,簡單地做:

​​

順便說一句,你手動調用的方法看起來很相似,但可能是可取:

//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方法(在做了更多的工作之後),我可以建議創建一個interface,traitabstract class來執行此操作?沿着線的東西:

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'); 
     } 
    } 
} 

警告
無這段代碼的測試,我只是寫在這裏把我的頭頂部,很可能包含錯誤。

相關問題