Я использую гидратацию массива Doctrine и подсказку HINT_INCLUDE_META_COLUMNS
в своем запросе для генерации результатов, содержащих внешние ключи связанных сущностей:
[
'id' => 1,
'title' => 'Example Post',
'author__id' => 2,
'image__id' => 2,
'image' => [
'id' => 2,
'file' => 'example.jpg'
],
];
Однако мне бы хотелось, чтобы вместо этого данные должны быть структурированы следующим образом:
[
'id' => 1,
'title' => 'Example Post',
'author' => [
'id' => 2,
],
'image' => [
'id' => 2,
'file' => 'example.jpg'
],
];
Так, чтобы пути к идентификаторам FK всегда были одинаковыми, независимо от того, было ли отношение объединено в запросе, и независимо от того, является ли массив массивом или нет или использовалась гидратация объекта.
До сих пор я придумал очень простое решение, расширив массив Doctrine. Это делает то, что мне нужно, но не очень хорошо, так как это удваивает время, необходимое для гидратации данных:
class ArrayHydrator extends DoctrineArrayHydrator
{
protected function hydrateRowData(array $row, array &$result)
{
parent::hydrateRowData($row, $result);
$parse = function(&$array) use (&$parse) {
foreach ($array as $name => &$value) {
if (is_array($value)) {
$parse($value);
} else if (strpos($name, '__') !== false) {
list($rel, $col) = explode('__', $name);
unset($array[$name]);
if (isset($value)) {
$array[$rel][$col] = $value;
}
}
}
};
$parse($result);
}
}
Я также попытался дублировать гидратор массива Doctrine и выполнить это изменить во время первоначальной гидратации, но я не могу понять, где это можно сделать безопасно, поскольку мои попытки всегда приводят к потере данных из соединенных отношений (ie. Приведенный выше ключ image
просто заменяется с идентификатором FK).
Кто-нибудь знает, как я могу добиться этого нехорошим / эффективным способом?