我应该使用什么模式将PHP关联数组转换为复杂的对象图?

时间:2012-03-08 18:49:49

标签: php oop design-patterns

我的数据以关联数组的形式到达。这是有效的,但我的代码是一堆嵌套数组,我想开始使用适当的OO / Objects来使这些数据更容易使用。我不能改变我收到这些数据的方式,所以我想找到一种干净的方法将关联数组转换成我的类的实例。

我有这些类来为我的应用程序中的People建模:

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数组函数来完成所有这些操作,但这看起来很混乱并容易出错。有没有更简单的方法可以快速水化/脱水这些物体?

3 个答案:

答案 0 :(得分:3)

将此添加到Hobby

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

答案 1 :(得分:1)

这可能效果不好(因为我现在无法测试),但尝试这样的事情:

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

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

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

答案 2 :(得分:0)

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

示例:

$person = json_decode($json);

echo $person->name;
echo $person->dogs[0]->breed;

$person->name = "Jim";

$json = json_encode($person);

如果您想继续使用自定义类,则需要一些工作。请参阅此question