从Doctrine2获取值数组的正确方法

时间:2015-01-04 19:27:21

标签: php symfony doctrine-orm

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

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

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内置方法是否存在更清晰的方法?我尝试过不同的水合模式,但没有任何效果。

提前致谢:)

4 个答案:

答案 0 :(得分:6)

你可能create a custom hydrator,但实际上就像你现在的方式一样没有问题。您也可以通过以下方式完成此操作:

PHP< = 5.4

return array_map('current', $addresses);

PHP> = 5.5

return array_column('email', $addresses);

{* 1}}函数是在PHP 5.5.0中引入的,可以满足您的需求。 array_column函数将起作用,调用PHP的内部array_map函数,它只返回当前元素的值(总是初始化为该数组的第一个元素)。

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

答案 1 :(得分:1)

您可以使用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);
}

答案 2 :(得分:0)

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

getResult(混合$ hydrationMode = Doctrine \ ORM \ AbstractQuery :: HYDRATE_OBJECT)

答案 3 :(得分:0)

我宁愿使用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());
}