Как вернуть массивы JSON вместо объектов, используя ORM FuelPHP и Controller_Rest

Controller_Something extends Controller_Rest {
  public function get_something() {    
    $query = Model_Something::query()->related('hasMany')->get();
    return $this->response($query);
  }
}

Возвращает:

{
  stuff: here,
  looks: good,
  hasMany: {
    151251: {
      id: 151251,
      other: stuff
    }
  }
}

Я хочу, чтобы отношения были массивами:

{
  stuff: here,
  looks: good,
  hasMany: [
    {
      id: 151251,
      other: stuff
    }
  ]
}

Это происходит потому, что ORM возвращает связанные массивы результатов с ключами, соответствующими PKEY записи, и JSON интерпретирует это как объект. Я хочу, чтобы эти массивы проходили через array_values() или что-то в этом роде, поэтому результат JSON будет использовать Array.

В настоящее время я делаю это, чтобы "решить" проблему:

$res = Format::forge($result_set)->to_array();
$res['hasMany'] = array_values($res['hasMany']);
return $this->response($res);

Но это полезно только для одного или двух уровней, где, как я знаю, будут данные.

Если есть отношения, которые не гарантированы, мне не нужно проверять на ошибки каждое потенциальное подмножество сложной Модели.

Я просто хочу, чтобы все массивы «один-ко-многим» вводились последовательно, а не по записям PKEY.


person willoller    schedule 10.06.2013    source источник


Ответы (4)


Короче говоря: вы не можете, если не создадите хук в Query:hydrate https://github.com/fuel/orm/blob/1.7/develop/classes/query.php#L1083 или затенение класса Query некоторой реализацией, которая возвращает те же результаты, за исключением hydrate.

person Ast Derek    schedule 01.07.2013

$query = Model_Something::find()->related('hasMany');

возвращает объект запроса в ‹ 1.6, исключение в 1.6 и null в 1.6.1+. Поэтому я предполагаю, что вы делаете что-то еще, что приводит к такому результату.

Если вы хотите получить в результате массивы вместо объектов, вам необходимо преобразовать результат. Вы можете сделать это, вызвав to_array() для объекта модели или используя класс Format для преобразования массива объектов модели в массив: $result = \Format::forge($result)->to_array();

person WanWizard    schedule 11.06.2013
comment
Format::forge() это не то, что я хочу; исходящий JSON по-прежнему основан на массиве с идентификатором и будет выражен как объект JSON, а не как массив. Я добавлю свой текущий обходной путь, чтобы показать это. - person willoller; 11.06.2013
comment
+1 за указание на то, что find() устарело в пользу query() :) - person willoller; 11.06.2013
comment
я понимаю, вам нужен индексированный массив. Это не будет создано, ORM использует значение индекса массива для хранения PK связанной записи, чтобы его можно было найти. array_values(), вероятно, лучший вариант. - person WanWizard; 01.09.2013

function object_to_array($data){
         $new_data2= array();
         $keys   =   array_keys((array)$data);
         foreach ($keys as $key)
        {
            $value  =   $data[$key];

            if(is_numeric($key))
            {
                $new_data2[]    =   object_to_array($value);

            }elseif(is_string($value) || is_null($value))
            {
                $new_data2[$key]    =   $data[$key];
            }else
            {
                $new_data2[$key]    =   object_to_array($value);
            }

        }

        return $new_data2;
    }
$formattedArray  =   \Format::forge(Model_Product::query()->get())->to_array();

$cleanData=object_to_array($formattedArray);

echo \Format::forge($cleanData)->to_json();

Таким образом проверяется ключ массива; если ключ является числом, а значение является объектом или массивом, чистый ключ

person İbrahim Ş. Örencik    schedule 31.05.2016
comment
Хотя этот код может решить проблему, вы всегда должны сопровождать свой код объяснением. - person Natalie Hedström; 01.06.2016
comment
Я согласен с тобой, но у меня плохой английский - person İbrahim Ş. Örencik; 06.06.2016

Программно это можно сделать. Следуя приведенной ниже модели, но для очень глубоких отношений не интересен сложностью алгоритма.

Модель:

class Model_Something extends \Orm\Model
{
    ...

    public function relatedAsArray()
    {
        $this->relationsAsArray($this->_data_relations);
    }

    private function relationsAsArray(&$relations)
    {
        foreach ($relations as $key => $relation) {
            foreach ($relation as $fields) {
                foreach ($fields as $field) {
                    if (isset($field->_data_relations)) {
                        $this->relationsAsArray($field->_data_relations);
                    }
                }
            }

            if (is_array($relation)) {
                $relations[$key] = array_values($relation);
            }
        }
    }
}

Вызов метода:

$something = Model_Something::find($somethingId, array('related' => array('hasMany', 'hasMany.hasOthers')));

$something->relatedAsArray();

Результат был именно таким, как вы хотели.

Результат:

{
  stuff: here,
  looks: good,
  hasMany: [
    {
      id: 151251,
      other: stuff,
      hasOthers: [
          {
            id: 12312,
            field: other
          }, ...
      ]
    }, ...
  ]
}
person saulopaiva    schedule 12.12.2015