【问题标题】:What pattern should I use to convert PHP associative arrays to/from complex Object graphs?我应该使用什么模式将 PHP 关联数组转换为复杂对象图/从复杂对象图转换?
【发布时间】:2012-03-26 06:11:45
【问题描述】:

我的数据以关联数组的形式到达。这可行,但我的代码是一堆嵌套数组,我想开始使用适当的 OO/Objects 来使这些数据更易于使用。我无法更改接收这些数据的方式,因此我想找到一种干净的方法将关联数组转换为下面我的类的实例。

我有这些类来模拟我的应用程序中的人:

class Person {
  /**
   * @var string
   */
  private $_name;

  /**
   * @var array[Dog]
   */
  private $_dogs = array();

  /**
   * @var array[Hobby]
   */
  private $_hobbies = array();
}

class Dog {
  /**
   * @var string
   */
  private $_color;

  /**
   * @var string
   */
  private $_breed;
}

class Hobby {
  /**
   * @var string
   */
  private $_description;
  /**
   * @var int
   */
  private $_cost;
}

我的数据(JSON 格式)如下所示:

'person': {
  'name': 'Joe',
  'dogs': [
     {'breed': 'Husky', 'color': 'Black'},
     {'breed': 'Poodle', 'color': 'Yellow'}
   ]
  'hobbies': [
     {'description': 'Skiing', 'cost': 500},
     {'description': 'Running', 'cost': 0}
   ]
}

我可以使用 json_decode 轻松将此 JSON 转换为关联数组,但困难在于将每个嵌套的 HobbyPet 对象转换为适当的类,然后当我想要关联数组返回时,将这些对象再次转换为关联数组。

我可以通过在我的每个类中编写一个 to/from 数组函数来完成这一切,但这看起来相当混乱且容易出错。有没有更直接的方法可以让这些物体快速水合/脱水?

【问题讨论】:

    标签: php oop design-patterns


    【解决方案1】:

    将此添加到爱好

    public function fromArray($array){
    
    if(isset($array['description'])){
        $this->_description = $array['description'];
    }
    if(isset($array['cost'])){
        $this->_cost = $array['cost'];
    }
    }
    
    public function toArray(){
    
    $array = array();
    $array['description'] = $this->_description;
    $array['cost'] = $this->_cost;
    return $array;
    }
    

    这是给狗的:

    public function fromArray($array){
    
    if(isset($array['breed'])){
        $this->_breed = $array['breed'];
    }
    if(isset($array['cost'])){
        $this->_cost = $array['color'];
    }
    }
    
    public function toArray(){
    
    $array = array();
    $array['breed'] = $this->_breed;
    $array['color'] = $this->_color;
    return $array;
    }
    

    在 Person 类中:

    public function fromArray($array){
    
    if(isset($array['name'])){
        $this->_name = $array['name'];
    }
    if(isset($array['dogs'])){
        foreach($array['dogs'] as $dogArray){
            $dog = new Dog();
            $dog->fromArray($dogArray);
            $this->_dogs[] = $dog;
        }
    }
    
    if(isset($array['hobbies'])){
        foreach($array['hobbies'] as $hobbyArray){
            $hobby = new Hobby();
            $hobby->fromArray($hobbyArray);
            $this->_hobbies[] = $hobby;
        }
    }
    }
    
    public function toArray(){
    
    $array = array();
    $array['name'] = $this->_name;
    foreach($this->_dogs as $dogObj){
        $array['dogs'][] = $dogObj->toarray();;
    }
    foreach($this->_hobbies as $hobbyObj){
        $array['hobbies'][] = $hobbyObj->toarray();;
    }
    return $array;
    }
    

    【讨论】:

      【解决方案2】:

      如果您使用 JSON 进行大量解码/编码(正如您提到的,您需要在关联数组和对象之间来回切换),我会确保转换为自定义类是有正当理由的。

      例子:

      $person = json_decode($json);
      
      echo $person->name;
      echo $person->dogs[0]->breed;
      
      $person->name = "Jim";
      
      $json = json_encode($person);
      

      如果您想继续使用自定义类,则需要一些工作。看到这个question

      【讨论】:

        【解决方案3】:

        这可能无法完美运行(因为我目前无法对其进行测试),但请尝试以下操作:

        $data = json_decode($jsonData, TRUE);
        $myObj = new Object();
        foreach($data as $key => $val) {
          $myObj->$key = $val;
        }
        

        我为第二个参数传递了 TRUE,否则 json_decode 将返回 stdClass 对象。我想用 foreach 把它当作一个关联数组来处理。

        我意识到我没有给出设计模式的名称,但我无法自信地回答这个问题。这是对类似问题的另一个回复:PHP Design Pattern

        【讨论】:

          猜你喜欢
          • 2022-01-21
          • 2021-11-04
          • 2013-03-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多