Я хочу получить массив значений из столбца id таблицы аукциона. Если бы это был необработанный SQL, я бы написал:
SELECT id FROM auction
Но когда я делаю это в Доктрине и выполняю:
$em->createQuery("SELECT a.id FROM Auction a")->getScalarResult();
Я получаю такой массив:
array( array('id' => 1), array('id' => 2), )
Вместо этого я хотел бы получить такой массив:
array( 1, 2 )
Как я могу это сделать с помощью Doctrine?
Вы можете использовать array_map
, и поскольку у вас есть только элемент в массиве, вы можете элегантно использовать 'current'
качестве обратного вызова вместо написания закрытия .
$result = $em->createQuery("SELECT a.id FROM Auction a")->getScalarResult(); $ids = array_map('current', $result);
См . Ниже ответ Петра Соботки для дополнительной информации об использовании памяти.
Как ответ jcbwlkr ниже , рекомендуется использовать array_column
.
Начиная с PHP 5.5 вы можете использовать array_column для решения этой проблемы
$result = $em->createQuery("SELECT a.id FROM Auction a")->getScalarResult(); $ids = array_column($result, "id");
Лучшим решением является использование PDO:FETCH_COLUMN
. Для этого вам нужен специальный гидратор:
//MyProject/Hydrators/ColumnHydrator.php namespace DoctrineExtensions\Hydrators\Mysql; use Doctrine\ORM\Internal\Hydration\AbstractHydrator, PDO; class ColumnHydrator extends AbstractHydrator { protected function hydrateAllData() { return $this->_stmt->fetchAll(PDO::FETCH_COLUMN); } }
Добавьте его в Доктрину:
$em->getConfiguration()->addCustomHydrationMode('COLUMN_HYDRATOR', 'MyProject\Hydrators\ColumnHydrator');
И вы можете использовать его так:
$em->createQuery("SELECT a.id FROM Auction a")->getResult("COLUMN_HYDRATOR");
Дополнительная информация: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html#custom-hydration-modes
Ответ Аскариуса изящный, но остерегайтесь использования памяти! array_map()
создает копию переданного массива и эффективно удваивает использование памяти. Если вы работаете с сотнями тысяч элементов массива, это может стать проблемой. Поскольку время вызова PHP 5.4 по ссылке было удалено, поэтому вы не можете сделать
// note the ampersand $ids = array_map('current', &$result);
В этом случае вы можете пойти с очевидным
$ids = array(); foreach($result as $item) { $ids[] = $item['id']; }
Я думаю, что это невозможно в Доктрине. Просто преобразуйте массив результатов в структуру данных, которую вы хотите использовать с помощью PHP:
$transform = function($item) { return $item['id']; }; $result = array_map($transform, $em->createQuery("SELECT a.id FROM Auction a")->getScalarResult());