How to get a one-dimensional scalar array as a doctrine dql query result?

后端 未结 5 1525
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-02 06:20

I want to get an array of values from the id column of the Auction table. If this was a raw SQL I would write:

SELECT id FROM auction

But w

相关标签:
5条回答
  • 2020-12-02 06:54

    PHP < 5.5

    You can use array_map, and since you only have on item per array, you can elegantly use 'current' as callback, instead of writing a closure.

    $result = $em->createQuery("SELECT a.id FROM Auction a")->getScalarResult();
    $ids = array_map('current', $result);
    

    See Petr Sobotka's answer below for additional info regarding memory usage.

    PHP >= 5.5

    As jcbwlkr's answered below, the recommended way it to use array_column.

    0 讨论(0)
  • 2020-12-02 06:56

    A better solution is to use PDO:FETCH_COLUMN . To do so you need a custom hydrator:

    //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);
        }
    }
    

    Add it to Doctrine:

    $em->getConfiguration()->addCustomHydrationMode('COLUMN_HYDRATOR', 'MyProject\Hydrators\ColumnHydrator');
    

    And you can use it like this:

    $em->createQuery("SELECT a.id FROM Auction a")->getResult("COLUMN_HYDRATOR");
    

    More info: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html#custom-hydration-modes

    0 讨论(0)
  • 2020-12-02 06:59

    As of PHP 5.5 you can use array_column to solve this

    $result = $em->createQuery("SELECT a.id FROM Auction a")->getScalarResult();
    $ids = array_column($result, "id");
    
    0 讨论(0)
  • 2020-12-02 07:04

    I think it's impossible in Doctrine. Just transform result array into the data structure you want using PHP:

    $transform = function($item) {
        return $item['id'];
    };
    $result = array_map($transform, $em->createQuery("SELECT a.id FROM Auction a")->getScalarResult());
    
    0 讨论(0)
  • 2020-12-02 07:09

    Ascarius' answer is elegant, but beware of memory usage! array_map() creates a copy of passed array and effectively doubles memory usage. If you work with hundreds of thousands of array items this can become an issue. Since PHP 5.4 call-time pass by reference has been removed so you cannot do

    // note the ampersand
    $ids = array_map('current', &$result);
    

    In that case you can go with obvious

    $ids = array();
    foreach($result as $item) {
      $ids[] = $item['id'];
    }
    
    0 讨论(0)
提交回复
热议问题