A mágica da ordenação: como o PHP organiza arrays bidimensionais
\n\nImagine: você tem uma tabela com dados — uma lista de usuários, produtos ou pedidos. Você precisa ordená-la por idade, preço ou data. No Excel, isso é feito com um clique. E no PHP? É aqui que a coisa fica interessante. A pergunta "Sort a 2d array by a column value" no Stack Overflow acumulou milhares de visualizações por um bom motivo — é um daqueles desafios que todo desenvolvedor enfrenta.
\n\nHoje, não vamos apenas fornecer o código pronto. Vamos mergulhar "sob o capô" do PHP e entender como os mecanismos de ordenação de array multidimensional realmente funcionam. Você descobrirá por que o usort é mais rápido que loops, como o PHP compara elementos e quais armadilhas esperam os iniciantes. Vamos nessa!
O problema: por que ordenar um array 2D não é trivial?
\n\nO PHP tem sort() e asort() para arrays unidimensionais. Mas quando o array se torna bidimensional (array de arrays), as funções padrão falham. Por quê? Porque o PHP não sabe por qual "coluna" (chave do array interno) você deseja ordenar.
Aqui está um exemplo típico:
\n\n<?php\n$users = [\n ['name' => 'Ana', 'age' => 25],\n ['name' => 'João', 'age' => 30],\n ['name' => 'Maria', 'age' => 22]\n];\n// Como ordenar por idade?\n?>\n\nSimplesmente chamar sort($users)? Não — o PHP emitirá um aviso e fará algo inesperado. É necessária uma abordagem mais inteligente.
Solução nº 1: O clássico usort com função personalizada
\n\nA maneira mais popular é usar usort(). Esta função recebe um array e uma função de callback, que determina a ordem de classificação. Vamos analisá-la "sob o capô".
Como o usort funciona?
\n\nQuando você chama usort($array, $callback), o PHP faz o seguinte:
- \n
- Divide o array em pares de elementos. \n
- Para cada par, chama sua função de callback. \n
- O callback deve retornar: um número negativo (se o primeiro elemento for "menor"), zero (se forem iguais) ou um número positivo (se o primeiro for "maior"). \n
- Com base nessas respostas, o PHP reorganiza os elementos usando o algoritmo Quicksort ou um híbrido dele. \n
Veja como fica no código:
\n\n<?php\n$users = [\n ['name' => 'Ana', 'age' => 25],\n ['name' => 'João', 'age' => 30],\n ['name' => 'Maria', 'age' => 22]\n];\n\nusort($users, function($a, $b) {\n return $a['age'] - $b['age'];\n});\n\nprint_r($users);\n// Resultado: Maria (22), Ana (25), João (30)\n?>\n\nObserve: subtraímos a idade de $b da idade de $a. Se $a['age'] for menor, o resultado é negativo e o elemento $a vem primeiro. Simples assim.
Armadilha: strings e diferença entre maiúsculas e minúsculas
\n\nSe você estiver ordenando por um campo de string (por exemplo, nome), a subtração não funcionará. É necessário usar strcmp() ou strcasecmp() para ordenação sem distinção entre maiúsculas e minúsculas:
<?php\nusort($users, function($a, $b) {\n return strcmp($a['name'], $b['name']);\n});\n// Ordenação por nome (Ana, João, Maria)\n?>\n\nMas cuidado: strcmp() diferencia maiúsculas de minúsculas. "apple" e "Apple" serão considerados diferentes. Se isso for crítico, use strcasecmp().
Solução nº 2: array_multisort — poderoso, mas complicado
\n\nA segunda maneira popular é array_multisort(). Esta função consegue ordenar vários arrays ao mesmo tempo ou um array multidimensional por uma coluna. "Sob o capô", ela funciona de forma diferente: extrai a coluna, a ordena e, em seguida, reorganiza os outros arrays na mesma ordem.
Veja como fica:
\n\n<?php\n$users = [\n ['name' => 'Ana', 'age' => 25],\n ['name' => 'João', 'age' => 30],\n ['name' => 'Maria', 'age' => 22]\n];\n\n// Extrai a coluna 'age' e ordena\narray_multisort(array_column($users, 'age'), SORT_ASC, $users);\n\nprint_r($users);\n// Resultado: Maria (22), Ana (25), João (30)\n?>\n\nO array_column() extrai todos os valores de 'age' em um novo array, que é então ordenado. O array_multisort() usa essa ordenação para reorganizar o array original. É elegante, mas pode ser confuso para iniciantes.