2009-10-27 10 views

Odpowiedz

9

Właśnie patrzyłem na ten sam problem. Trzeba przekonwertować Doctrine_Collection do tablicy:

$someDbObject = Doctrine_Query::create()...; 
$children = $someDbObject->Children; 
$children = $children->getData(); // convert from Doctrine_Collection to array 

Następnie można utworzyć funkcję niestandardową sortowania i nazywają go:

// sort children 
usort($children, array(__CLASS__, 'compareChildren')); // fixed __CLASS__ 

Gdzie compareChildren wyglądał:

private static function compareChildren($a, $b) { 
    // in this case "label" is the name of the database column 
    return strcmp($a->label, $b->label); 
} 
+2

rozwiązanie działa tylko kiedy zmienił go do: usort ($ dzieci, array (_____ CLASS_____ 'compareChildren')); – stoefln

31

ty może również:

$this->hasMany('Category as Categories', array(... 
      'orderBy' => 'title ASC')); 

W pliku schematu wygląda tak:

Relations: 
    Categories: 
     class: Category 
     .... 
     orderBy: title ASC 
+5

Jeśli sortowanie jest "trwałe", użycie tego sposobu jest o wiele lepsze niż użycie Chrisa Williama. – avetisk

+2

Minusem jest trwałość. Dodanie zamówienia do KAŻDEJ zapytania dla tej relacji wpłynie na wydajność. –

+0

lub adnotacja @ @ OrderBy': http://docs.doctrine-project.org/en/2.0.x/reference/annotations-reference.html#annref-orderby – zizoujab

3

Można dodać funkcję sortowania do Colletion.php:

public function sortBy($sortFunction) 
{ 
    usort($this->data, $sortFunction); 
} 

Sortowanie Doctrine_Collection użytkowników od ich wieku będzie wyglądać następująco:

class ExampleClass 
{ 

    public static function sortByAge($a , $b) 
    { 
     $age_a = $a->age; 
     $age_b = $b->age; 

     return $age_a == $age_b ? 0 : $age_a > $age_b ? 1 : - 1; 
    }  

    public function sortExample() 
    { 
     $users = User::getTable()->findAll(); 
     $users ->sortBy('ExampleClass::sortByAge'); 

     echo "Oldest User:"; 
     var_dump ($users->end()); 
    } 

} 
9

można użyć zbiórki iterator:

$collection = Table::getInstance()->findAll(); 

$iter = $collection->getIterator(); 
$iter->uasort(function($a, $b) { 
    $name_a = (int)$a->getName(); 
    $name_b = (int)$b->getName(); 

    return $name_a == $name_b ? 0 : $name_a > $name_b ? 1 : - 1; 
});   

foreach ($iter as $element) { 
    // ... Now you could iterate sorted collection 
} 

Jeśli chcesz uporządkować kolekcję przy użyciu metody __toString, to będzie dużo łatwiejsze:

foreach ($collection->getIterator()->asort() as $element) { /* ... */ } 
+1

Próbowałem używając '$ collection-> getIterator() -> asort()', ale po prostu zwraca bool. –

+0

Przepraszam, zapomniałem jak to działa. Masz rację, to zwraca true w przypadku sukcesu i false w przypadku niepowodzenia. Taki ładny design. – temochka

+0

Jest szansa, że ​​jeśli wywołasz gest przed ponownym iterowaniem, będziesz mógł przeglądać posortowaną listę. –