问题
Controller_Something extends Controller_Rest {
public function get_something() {
$query = Model_Something::query()->related('hasMany')->get();
return $this->response($query);
}
}
Returns:
{
stuff: here,
looks: good,
hasMany: {
151251: {
id: 151251,
other: stuff
}
}
}
I want the relations as arrays:
{
stuff: here,
looks: good,
hasMany: [
{
id: 151251,
other: stuff
}
]
}
This happens because the ORM returns related result arrays with keys corresponding to the record's PKEY, and JSON interprets this as an Object. I want these arrays to go through array_values()
or something, so the JSON result will use Array.
Currently I am doing this to "solve" the problem:
$res = Format::forge($result_set)->to_array();
$res['hasMany'] = array_values($res['hasMany']);
return $this->response($res);
But this is only useful to one or two levels, where I know the data will be.
If there are relations that are not guaranteed, I don't what to have to error-check every potential subset of a complex Model.
I just want all the one-to-many arrays to be keyed sequentially instead of by the records PKEY.
回答1:
In short: you can't unless you create a hook in Query:hydrate
https://github.com/fuel/orm/blob/1.7/develop/classes/query.php#L1083, or shadowing the Query
class with some implementation that returns the very same results except for hydrate
.
回答2:
$query = Model_Something::find()->related('hasMany');
returns a query object in < 1.6, an exception in 1.6, and null in 1.6.1+. So I assume you do something else that produces that result.
If you want arrays as a result instead of objects, you need to convert the result. You can do that by calling to_array()
on a model object, or by using the Format class to convert an array of model objects to an array:
$result = \Format::forge($result)->to_array();
回答3:
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();
This way checks the array key; if key is number and value is object or array clean key
回答4:
Programmatically it is possible to be done. Following the model below, but for very deep relationships is not interesting by the complexity of the algorithm.
Model:
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);
}
}
}
}
Call of method:
$something = Model_Something::find($somethingId, array('related' => array('hasMany', 'hasMany.hasOthers')));
$something->relatedAsArray();
The result was exactly like you wanted.
Result:
{
stuff: here,
looks: good,
hasMany: [
{
id: 151251,
other: stuff,
hasOthers: [
{
id: 12312,
field: other
}, ...
]
}, ...
]
}
来源:https://stackoverflow.com/questions/17033685/how-do-i-return-json-arrays-instead-of-objects-using-fuelphps-orm-and-controlle