Какой шаблон я должен использовать для преобразования ассоциативных массивов PHP в / из сложных графов объектов? - PullRequest
2 голосов
/ 08 марта 2012

Мои данные поступают в виде ассоциативных массивов. Это работает, но мой код - беспорядок вложенных массивов, и я хотел бы начать использовать надлежащие 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 в ассоциативный массив, используя json_decode, но возникают трудности с преобразованием каждого из вложенных объектов Hobby и Pet в соответствующие классы, а затем, когда я хочу вернуть ассоциативный массив , снова превращая эти объекты в ассоциативные массивы.

Я могу сделать все это, написав функцию массива to / from в каждом из моих классов, но это выглядит довольно грязно и подвержено ошибкам. Есть ли более простой способ, которым я могу быстро гидратировать / обезвоживать эти объекты?

Ответы [ 3 ]

3 голосов
/ 09 марта 2012

Добавить это в хобби

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 голос
/ 08 марта 2012

Это может не работать идеально (так как я не могу проверить это в данный момент), но попробуйте что-то вроде этого:

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

Я передал TRUE для второго параметра, потому что в противном случае json_decode вернет объект stdClass. Я хочу обрабатывать его как ассоциативный массив с foreach.

Я понимаю, что я не назвал шаблон проектирования, но я не могу ответить на это с уверенностью. Вот еще один ответ на аналогичный вопрос: PHP Design Pattern

0 голосов
/ 08 марта 2012

Если вы выполняете много декодирования / кодирования с помощью JSON (как вы упоминаете, вам нужно переходить назад и вперед между ассоциативными массивами и объектами), я хотел бы убедиться, что есть законная причина для преобразования в пользовательские классы. *

Пример:

$person = json_decode($json);

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

$person->name = "Jim";

$json = json_encode($person);

Если вы хотите продолжить работу с пользовательским классом, потребуется некоторая работа. Смотрите этот вопрос .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...