从 Doctrine2 获取一系列值的正确方法


Proper way to get an array of values from Doctrine2

我目前正在编写一个时事通讯系统。为了发送邮件,我需要从我的数据库中获取所有电子邮件地址(当然)。

所以我创建了一个自定义存储库方法,如下所示:

public function getEmailAddresses()
{
    $query = $this->getEntityManager()->createQueryBuilder()
        ->select('u.email')
        ->from('AppBundle:User', 'u')
        ->where('u.isNewsletterSubscriber = true')
    ;
    $results =  $query->getQuery()->getResult();
    $addresses = [];
    foreach($results as $line) {
        $addresses[] = $line['email'];
    }
    return $addresses;
}

我想知道是否有比处理结果以获得仅包含电子邮件地址的"纯"数组更好的方法。实际上,在$query->getQuery()->getResult()之后,我得到这样的东西:

'results' =>
 [0] => array('email' => 'first@email.com')
 [1] => array('email' => 'second@email.com')

正如我所说,我想要这样的东西:

array('first@email.com', 'second@email.com')

使用 Doctrine2 内置方法是否存在更简洁的方法?我尝试过不同的补水模式,但没有任何效果。

提前致谢:)

您可能可以创建一个自定义补水器,但是按照现在的方式进行操作确实没有问题。 您也可以通过以下方式执行此操作:

PHP <= 5.4

return array_map('current', $addresses);

PHP>= 5.5

return array_column($addresses, 'email');

array_column函数是在 PHP 5.5.0 中引入的,可以满足您的需求。 array_map函数将以其他方式工作,调用 PHP 的内部 current 函数,该函数仅返回当前元素的值(始终初始化为该数组的第一个元素)。

如果返回大量行,请小心使用 array_map,因为它可能会更慢,并且由于它必须复制数组,它肯定会占用更多内存。

你可以用 doctrine (DBAL) 运行纯 sql:

例:

public function getEmails()
{
    $connection = $this->getEntityManager()->getConnection()->prepare('SELECT u.email FROM user AS u');
    $connection->execute();
    return $connection->fetchAll('PDO::FETCH_COLUMN);
}

尝试其他$hydrationModes,也许有帮助

getResult( mixed $hydrationMode = Doctrine''ORM''AbstractQuery::HYDRATE_OBJECT )

我宁愿使用getArrayResult方法,所以教义不能水化每个对象(这是教义的昂贵任务)。

public function getEmailAddresses()
{
    $q = $this->getEntityManager()->createQuery('SELECT u.email FROM AppBundle:User u WHERE u.isNewsletterSubscriber = true');
    return array_map('current', $q->getArrayResult());
}