[symfony] How to sort findAll Doctrine's method?

I've been reading Doctrine's documentation, but I haven't been able to find a way to sort findAll() Results.

I'm using symfony2 + doctrine, this is the statement that I'm using inside my Controller:

$this->getDoctrine()->getRepository('MyBundle:MyTable')->findAll();

but I want the results to be ordered by ascending usernames.

I've been trying to pass an array as an argument this way:

findAll( array('username' => 'ASC') );

but it doesn't work (it doesn't complain either).

Is there any way to do this without building a DQL query?

This question is related to symfony doctrine-orm

The answer is


It's useful to look at source code sometimes.

For example findAll implementation is very simple (vendor/doctrine/orm/lib/Doctrine/ORM/EntityRepository.php):

public function findAll()
{
    return $this->findBy(array());
}

So we look at findBy and find what we need (orderBy)

public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)

You can sort an existing ArrayCollection using an array iterator.

assuming $collection is your ArrayCollection returned by findAll()

$iterator = $collection->getIterator();
$iterator->uasort(function ($a, $b) {
    return ($a->getPropery() < $b->getProperty()) ? -1 : 1;
});
$collection = new ArrayCollection(iterator_to_array($iterator));

This can easily be turned into a function you can put into your repository in order to create findAllOrderBy() method.


I use an alternative to the solution that wrote nifr.

$resultRows = $repository->fetchAll();
uasort($resultRows, function($a, $b){
    if ($a->getProperty() == $b->getProperty()) {
        return 0;
    }
    return ($a->getProperty()< $b->getProperty()) ? -1 : 1;
});

It's quicker than the ORDER BY clause, and without the overhead of the Iterator.


Try this:

$em = $this->getDoctrine()->getManager();

$entities = $em->getRepository('MyBundle:MyTable')->findBy(array(), array('username' => 'ASC'));

Simple:

$this->getDoctrine()->getRepository('AcmeBundle:User')->findBy(
    array(),
    array('username' => 'ASC')
);

You need to use a criteria, for example:

<?php

namespace Bundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\Common\Collections\Criteria;

/**
* Thing controller
*/
class ThingController extends Controller
{
    public function thingsAction(Request $request, $id)
    {
        $ids=explode(',',$id);
        $criteria = new Criteria(null, <<DQL ordering expression>>, null, null );

        $rep    = $this->getDoctrine()->getManager()->getRepository('Bundle:Thing');
        $things = $rep->matching($criteria);
        return $this->render('Bundle:Thing:things.html.twig', [
            'entities' => $things,
        ]);
    }
}

This works for me:

$entities = $em->getRepository('MyBundle:MyTable')->findBy(array(),array('name' => 'ASC'));

Keeping the first array empty fetches back all data, it worked in my case.


Modify the default findAll function in EntityRepository like this:

public function findAll( array $orderBy = null )
{
    return $this->findBy([], $orderBy);
}

That way you can use the ''findAll'' on any query for any data table with an option to sort the query


Look at the Doctrine API source-code :

class EntityRepository{
  ...
  public function findAll(){
    return $this->findBy(array());
  }
  ...
}

findBy method in Symfony excepts two parameters. First is array of fields you want to search on and second array is the the sort field and its order

public function findSorted()
    {
        return $this->findBy(['name'=>'Jhon'], ['date'=>'DESC']);
    }

$this->getDoctrine()->getRepository('MyBundle:MyTable')->findBy([], ['username' => 'ASC']);