Ordenação de array por valor de coluna em PHP: guia para quem está cansado de pesquisar
\n\nVocê já se deparou com uma situação em que tem uma lista de usuários, produtos ou pedidos em forma de array de arrays associativos e precisa ordená-los por algum campo? Digamos, por idade, preço ou data de registro. Se sim — você não está sozinho. Esta pergunta no Stack Overflow acumulou milhares de visualizações e dezenas de votos. E hoje vamos resolvê-la de uma vez por todas.
\n\nNeste artigo, não vamos apenas mostrar como funcionam usort e array_multisort. Vamos responder às perguntas mais frequentes que surgem entre os desenvolvedores: como ordenar por chave aninhada, como preservar chaves, como ordenar por vários campos e o que fazer quando os dados vêm do banco de dados.
Vamos lá!
\n\nO que é um array de arrays associativos e por que ordená-lo?
\n\nImagine que você tem uma lista de usuários:
\n\n$users = [\n ['name' => 'Ana', 'age' => 25, 'city' => 'Moscou'],\n ['name' => 'Boris', 'age' => 30, 'city' => 'São Petersburgo'],\n ['name' => 'Victor', 'age' => 22, 'city' => 'Kazan'],\n];\n\nEste é um típico array multidimensional em PHP, onde cada elemento é um array associativo com as mesmas chaves. Muitas vezes é necessário exibir essa lista ordenada por algum campo: por idade (do mais novo ao mais velho), por nome (em ordem alfabética) ou por cidade.
\n\nAs funções padrão do PHP como sort() ou asort() não ajudam aqui — elas funcionam com valores simples, não com estruturas aninhadas. São necessárias ferramentas especiais.
A maneira mais popular: usort com função anônima
\n\nSe você entrar no Stack Overflow e abrir a discussão "Sort an array of associative arrays by column value", em 90% dos casos vão recomendar usort. Isso é lógico: a função usort permite definir sua própria lógica de comparação entre dois elementos do array.
Como ordenar um array por um único campo (idade)
\n\nSuponha que queremos ordenar nossos usuários por idade em ordem crescente:
\n\n<?php\n$users = [\n ['name' => 'Ana', 'age' => 25, 'city' => 'Moscou'],\n ['name' => 'Boris', 'age' => 30, 'city' => 'São Petersburgo'],\n ['name' => 'Victor', 'age' => 22, 'city' => 'Kazan'],\n];\n\nusort($users, function($a, $b) {\n return $a['age'] <=> $b['age'];\n});\n\nprint_r($users);\n?>\n\nResultado:
\nArray\n(\n [0] => Array ( [name] => Victor [age] => 22 [city] => Kazan )\n [1] => Array ( [name] => Ana [age] => 25 [city] => Moscou )\n [2] => Array ( [name] => Boris [age] => 30 [city] => São Petersburgo )\n)\n\nObserve: estamos usando o operador nave espacial <=> (spaceship), que foi introduzido no PHP 7. Ele retorna -1, 0 ou 1, o que é ideal para funções de ordenação. Se precisar ordenar em ordem decrescente, basta trocar $a e $b de lugar:
usort($users, function($a, $b) {\n return $b['age'] <=> $a['age'];\n});\n\nOrdenação por campo de string (nome)
\n\nPara strings, é igualmente simples. Quer ordenar os usuários por nome em ordem alfabética? Aqui está:
\n\nusort($users, function($a, $b) {\n return strcmp($a['name'], $b['name']);\n});\n\nOu use novamente <=> — ele também funciona com strings:
usort($users, function($a, $b) {\n return $a['name'] <=> $b['name'];\n});\n\nPerguntas frequentes e armadilhas
\n\n1. Como ordenar por chave aninhada?
\n\nÀs vezes os dados têm uma estrutura mais profunda. Por exemplo, cada usuário tem um array profile