PHPで配列を並び替える際に便利なのが、usort()関数です。
PHPにはsort()やrsort()などのソート関数がありますが、usort()を使用すると、独自の条件を指定して配列を並び替えられます。
例えば、数値を昇順・降順に並び替えたり、商品データを価格順に並び替えたりすることが可能です。
また、複数の条件を組み合わせた並び替えにも対応しているため、ECサイトの商品一覧やブログの記事一覧、ランキング機能など、さまざまな場面で活用できます。
この記事では、PHPのusort()関数の基本的な使い方から、昇順・降順、多次元配列、文字列、日付の並び替え方法まで、サンプルコードを交えて詳しく解説します。
sort()やuasort()など、ほかのソート関数との違いや、使用する際の注意点も紹介するので、ぜひ参考にしてください。
PHPのusort()関数とは?
PHPのusort()は、ユーザーが定義した比較関数を使用して、配列の要素を並び替える組み込み関数です。
通常のsort()関数では、PHPが用意した比較ルールに従って配列を並び替えます。
一方、usort()では、どの要素を先に配置するかを比較関数で自由に指定できることが特徴です。
例えば、以下のような処理を実現できます。
- 数値を小さい順(昇順)に並び替える
- 数値を大きい順(降順)に並び替える
- 文字列をアルファベット順に並び替える
- 商品データを価格順に並び替える
- 記事データを公開日順に並び替える
- ユーザーデータを年齢やスコア順に並び替える
- 複数の条件を組み合わせて並び替える
特に、複数の項目を持つ多次元配列を並び替える場合に便利です。
usort()関数の基本構文
usort()の基本構文は、以下のとおりです。
usort($array, $callback);
それぞれの引数には、以下の値を指定します。
| 引数 | 説明 |
|---|---|
$array | 並び替えの対象となる配列 |
$callback | 配列の要素同士を比較する関数 |
第1引数には、並び替えたい配列を指定します。
第2引数には、2つの要素を比較する関数を指定します。
比較関数には、通常の関数や無名関数、アロー関数などを使用できます。
例えば、数値の配列を昇順に並び替える場合は、以下のように記述します。
$numbers = [5, 3, 8, 1, 4];
usort($numbers, function ($a, $b) {
return $a <=> $b;
});
print_r($numbers);
実行結果は以下のとおりです。
Array
(
[0] => 1
[1] => 3
[2] => 4
[3] => 5
[4] => 8
)
このように、配列の要素が小さい順に並び替えられます。
usort()関数の戻り値
usort()は、並び替えた配列を戻り値として返す関数ではありません。
引数に指定した配列そのものを変更し、戻り値としてtrueを返します。
PHP 8.2以降では、関数の戻り値の型もtrueとして定義されています。
$numbers = [5, 3, 8, 1, 4];
$result = usort($numbers, function ($a, $b) {
return $a <=> $b;
});
print_r($numbers);
var_dump($result);
実行結果は以下のとおりです。
Array
(
[0] => 1
[1] => 3
[2] => 4
[3] => 5
[4] => 8
)
bool(true)
$resultには、並び替え後の配列ではなくtrueが格納されています。
そのため、並び替え後のデータを取得する場合は、元の配列を参照してください。
また、並び替え前のデータを残したい場合は、事前に配列をコピーしておく必要があります。
$numbers = [5, 3, 8, 1, 4];
$sortedNumbers = $numbers;
usort($sortedNumbers, function ($a, $b) {
return $a <=> $b;
});
print_r($numbers);
print_r($sortedNumbers);
この方法なら、$numbersの内容を変更せずに、$sortedNumbersだけを並び替えられます。
usort()の比較関数の仕組み
usort()を正しく使用するためには、比較関数の仕組みを理解することが重要です。
比較関数は、配列の2つの要素を受け取り、どちらを先に配置するかを判断する役割を持っています。
比較関数の戻り値によって並び順が決まる
比較関数は、以下の3種類の結果を返します。
| 戻り値 | 意味 |
|---|---|
| 負の整数 | $aを$bより前に配置する |
0 | $aと$bを同じ順位として扱う |
| 正の整数 | $aを$bより後ろに配置する |
例えば、以下のような比較関数を使用します。
function ($a, $b) {
if ($a < $b) {
return -1;
}
if ($a > $b) {
return 1;
}
return 0;
}
この比較関数では、最初の値が2番目の値より小さい場合に-1を返します。
反対に、最初の値が大きい場合は1を返します。
2つの値が等しい場合は0を返す仕組みです。
このような比較を繰り返すことで、配列の要素が昇順に並び替えられます。
なお、usort()が比較関数を呼び出す回数や順序は、配列の内容やPHPの実装によって異なります。
比較関数が呼び出される順序に依存した処理は避けましょう。
宇宙船演算子(<=>)を使用する方法
PHP 7.0以降では、宇宙船演算子(Spaceship Operator)を使用できます。
宇宙船演算子は、2つの値を比較し、その大小関係に応じて負の整数、0、正の整数を返す演算子です。
例えば、以下のように使用します。
echo 3 <=> 5; // -1
echo 5 <=> 5; // 0
echo 8 <=> 5; // 1
そのため、先ほどの比較関数は、以下のように簡潔に記述できます。
function ($a, $b) {
return $a <=> $b;
}
usort()で数値を並び替える場合は、この宇宙船演算子を使用すると便利です。
ただし、比較時の型変換などにはPHPの比較ルールが適用されるため、比較対象のデータ型はできるだけ統一しておきましょう。
usort()で配列を昇順・降順に並び替える方法
usort()の基本的な使い方として、数値の配列を昇順・降順に並び替える方法を紹介します。
昇順とは数値を小さい順に並べることで、降順とは大きい順に並べることです。
数値を昇順(小さい順)に並び替える
数値を昇順に並び替える場合は、宇宙船演算子を使用して$a <=> $bと記述します。
$numbers = [50, 10, 30, 20, 40];
usort($numbers, function ($a, $b) {
return $a <=> $b;
});
print_r($numbers);
実行結果は以下のとおりです。
Array
(
[0] => 10
[1] => 20
[2] => 30
[3] => 40
[4] => 50
)
このように、数値が小さい順に並び替えられます。
数値を降順(大きい順)に並び替える
数値を降順に並び替える場合は、比較する値の順序を逆にします。
$numbers = [50, 10, 30, 20, 40];
usort($numbers, function ($a, $b) {
return $b <=> $a;
});
print_r($numbers);
実行結果は以下のとおりです。
Array
(
[0] => 50
[1] => 40
[2] => 30
[3] => 20
[4] => 10
)
昇順と降順の書き方をまとめると、以下のようになります。
| 並び替え方法 | 比較関数 |
|---|---|
| 昇順 | return $a <=> $b; |
| 降順 | return $b <=> $a; |
基本的には、比較する変数の順序を入れ替えるだけで、昇順と降順を切り替えられます。
アロー関数を使用して簡潔に記述する
PHP 7.4以降では、アロー関数を使用して比較関数を短く記述できます。
アロー関数とは、fnキーワードを使用して関数を簡潔に定義できる構文です。
例えば、昇順の並び替えは以下のように記述できます。
$numbers = [50, 10, 30, 20, 40];
usort($numbers, fn($a, $b) => $a <=> $b);
print_r($numbers);
降順の場合は、以下のようにします。
$numbers = [50, 10, 30, 20, 40];
usort($numbers, fn($a, $b) => $b <=> $a);
無名関数と比べてコードが短くなるため、単純な並び替えにはアロー関数が便利です。
usort()で文字列を並び替える方法
usort()は、数値だけでなく文字列の並び替えにも使用できます。
文字列を比較する場合は、strcmp()やstrcasecmp()などの関数を組み合わせる方法が一般的です。
文字列をアルファベット順に並び替える
文字列をアルファベット順に並び替える場合は、strcmp()を使用します。
strcmp()は、2つの文字列をバイト単位で比較する関数です。
$fruits = [
'orange',
'apple',
'grape',
'banana'
];
usort($fruits, function ($a, $b) {
return strcmp($a, $b);
});
print_r($fruits);
実行結果は以下のとおりです。
Array
(
[0] => apple
[1] => banana
[2] => grape
[3] => orange
)
このように、すべて小文字の英単語であれば、アルファベット順に並び替えられます。
ただし、strcmp()は大文字と小文字を区別します。
また、言語固有の並び替えルールを考慮する関数ではない点にも注意してください。
文字列を逆順に並び替える
文字列を逆順に並び替える場合は、strcmp()の引数を逆にします。
$fruits = [
'orange',
'apple',
'grape',
'banana'
];
usort($fruits, function ($a, $b) {
return strcmp($b, $a);
});
print_r($fruits);
実行結果は以下のとおりです。
Array
(
[0] => orange
[1] => grape
[2] => banana
[3] => apple
)
strcmp($a, $b)とstrcmp($b, $a)を使い分けることで、文字列の昇順・降順を切り替えられます。
大文字と小文字を区別せずに並び替える
英字の大文字と小文字を区別せずに並び替えたい場合は、strcasecmp()を使用します。
$fruits = [
'Banana',
'apple',
'Orange',
'grape'
];
usort($fruits, function ($a, $b) {
return strcasecmp($a, $b);
});
print_r($fruits);
実行結果は以下のとおりです。
Array
(
[0] => apple
[1] => Banana
[2] => grape
[3] => Orange
)
strcasecmp()は、ASCII英字の大文字と小文字を区別せずに比較します。
そのため、英字を中心とした文字列の並び替えに適しています。
一方、日本語やアクセント付き文字などを含む多言語の文字列を適切に並び替える場合は、後述するCollatorクラスなどを使用しましょう。
usort()で多次元配列を並び替える方法
usort()は、多次元配列の並び替えにも使用できます。
多次元配列とは、配列の要素として別の配列を持つデータ構造です。
例えば、商品名や価格などをまとめた商品データが該当します。
多次元配列を特定のキーで並び替える
以下の商品データを例に考えてみましょう。
$products = [
[
'name' => '商品A',
'price' => 3000
],
[
'name' => '商品B',
'price' => 1000
],
[
'name' => '商品C',
'price' => 2000
]
];
この配列には、商品名を表すnameと、価格を表すpriceが含まれています。
usort()では、比較関数の中で特定のキーを指定することにより、その値を基準に並び替えられます。
商品価格を安い順に並び替える
商品価格を安い順に並び替える場合は、priceの値を昇順で比較します。
usort($products, function ($a, $b) {
return $a['price'] <=> $b['price'];
});
print_r($products);
並び替え後の商品データは、以下のようになります。
| 商品名 | 価格 |
|---|---|
| 商品B | 1,000円 |
| 商品C | 2,000円 |
| 商品A | 3,000円 |
比較関数の中で$a['price']と$b['price']を比較することで、価格の安い順に並び替えています。
商品価格を高い順に並び替える
商品価格を高い順に並び替える場合は、比較する値の順序を逆にします。
usort($products, function ($a, $b) {
return $b['price'] <=> $a['price'];
});
print_r($products);
並び替え後の商品データは、以下のとおりです。
| 商品名 | 価格 |
|---|---|
| 商品A | 3,000円 |
| 商品C | 2,000円 |
| 商品B | 1,000円 |
このような処理は、ECサイトの商品一覧で「価格が安い順」「価格が高い順」を切り替える場合などに役立ちます。
なお、usort()では配列のキーが振り直されるため、商品IDなどを配列のキーとして管理している場合には注意が必要です。
usort()で複数条件を指定して並び替える方法
usort()では、複数の条件を組み合わせた並び替えも可能です。
例えば、ユーザーを年齢の若い順に並び替え、年齢が同じ場合はスコアの高い順に並び替えるといった処理を実現できます。
年齢とスコアの2つの条件で並び替える
以下のユーザーデータを例にします。
$users = [
['name' => '田中', 'age' => 30, 'score' => 80],
['name' => '佐藤', 'age' => 25, 'score' => 90],
['name' => '鈴木', 'age' => 30, 'score' => 95],
['name' => '高橋', 'age' => 25, 'score' => 70]
];
この配列を、以下の条件で並び替えます。
- 年齢が若い順に並び替える
- 年齢が同じ場合はスコアが高い順に並び替える
具体的なコードは以下のとおりです。
usort($users, function ($a, $b) {
// 年齢を昇順で比較
$result = $a['age'] <=> $b['age'];
// 年齢が異なる場合は比較結果を返す
if ($result !== 0) {
return $result;
}
// 年齢が同じ場合はスコアを降順で比較
return $b['score'] <=> $a['score'];
});
print_r($users);
実行結果を表にまとめると、以下のようになります。
| 名前 | 年齢 | スコア |
|---|---|---|
| 佐藤 | 25 | 90 |
| 高橋 | 25 | 70 |
| 鈴木 | 30 | 95 |
| 田中 | 30 | 80 |
まず年齢を比較し、年齢が同じ場合にスコアを比較しています。
このように、比較関数の中で条件分岐を行うことで、複数の条件を指定できます。
複数条件の並び替えを簡潔に記述する
複数条件による並び替えは、?:演算子を使用すると簡潔に記述できます。
usort($users, function ($a, $b) {
return ($a['age'] <=> $b['age'])
?: ($b['score'] <=> $a['score']);
});
?:演算子は、左側の値が偽と評価される場合に、右側の値を返す演算子です。
宇宙船演算子の比較結果は負の整数、0、正の整数となるため、最初の比較結果が0だった場合に、次の条件が評価されます。
今回の例では、年齢が同じ場合のみスコアを比較します。
この方法は、3つ以上の条件にも応用できます。
例えば、年齢、スコア、IDの順に比較する場合は、以下のように記述できます。
usort($users, function ($a, $b) {
return ($a['age'] <=> $b['age'])
?: ($b['score'] <=> $a['score'])
?: ($a['id'] <=> $b['id']);
});
ただし、この例では各要素にidキーが存在することを前提としています。
複数条件による並び替えを実装する場合は、比較に使用するキーがすべての要素に存在するか確認しましょう。
usort()で日付を並び替える方法
ブログの記事一覧やニュースサイトなどでは、日付順の並び替えがよく使用されます。
usort()を使用すると、記事の公開日や商品の登録日などを基準に並び替えることができます。
日付を新しい順に並び替える
以下の記事データを例にします。
$articles = [
[
'title' => '記事A',
'date' => '2026-01-10'
],
[
'title' => '記事B',
'date' => '2026-03-15'
],
[
'title' => '記事C',
'date' => '2026-02-20'
]
];
日付を新しい順に並び替える場合は、strtotime()を使用する方法があります。
usort($articles, function ($a, $b) {
return strtotime($b['date']) <=> strtotime($a['date']);
});
print_r($articles);
並び替え結果は以下のとおりです。
| 記事タイトル | 公開日 |
|---|---|
| 記事B | 2026-03-15 |
| 記事C | 2026-02-20 |
| 記事A | 2026-01-10 |
strtotime()は、日付文字列をUnixタイムスタンプに変換する関数です。
日付をタイムスタンプに変換して比較することで、新しい順や古い順に並び替えられます。
ただし、strtotime()は日付文字列を解析できなかった場合にfalseを返します。
そのため、実際のシステムでは、日付の形式や値が正しいかを事前に確認することが重要です。
YYYY-MM-DD形式なら文字列のまま比較できる
日付がすべてYYYY-MM-DD形式で統一されている場合は、文字列のまま比較することも可能です。
usort($articles, function ($a, $b) {
return strcmp($b['date'], $a['date']);
});
YYYY-MM-DD形式では、年、月、日の順に数値が並びます。
月や日もゼロ埋めされているため、形式が統一されていれば、文字列の大小関係と日付の前後関係が一致します。
この方法では、比較のたびにstrtotime()を実行する必要がありません。
ただし、日付文字列が正しい形式であることが前提です。
また、日時にタイムゾーン情報が含まれている場合や、複数のタイムゾーンを扱う場合は、単純な文字列比較では正しく並び替えられないことがあります。
DateTimeImmutableを使用して日付を比較する
日付をオブジェクトとして扱いたい場合は、DateTimeImmutableを使用する方法もあります。
usort($articles, function ($a, $b) {
$dateA = new DateTimeImmutable($a['date']);
$dateB = new DateTimeImmutable($b['date']);
return $dateB <=> $dateA;
});
DateTimeImmutableは、日付や時刻を扱うためのPHPのクラスです。
日付オブジェクト同士を比較することで、日時の前後関係を判定できます。
ただし、不正な日付文字列を渡した場合は例外が発生することがあるため、必要に応じてエラー処理を実装してください。
また、大量のデータを並び替える場合は、比較関数の中で毎回日付オブジェクトを生成するよりも、ソート前にデータを変換しておくほうが効率的です。
usort()で日本語を五十音順に並び替える方法
PHPで日本語の文字列を並び替える場合は、英数字とは異なる点に注意が必要です。
strcmp()は文字列をバイト単位で比較するため、日本語の五十音順に並び替える用途には適していません。
日本語を並び替える場合は、PHPのintl拡張機能で提供されるCollatorクラスを使用する方法があります。
Collatorクラスを使用して日本語を並び替える
以下の日本語データを例にします。
$names = [
'さとう',
'たなか',
'あおき',
'やまだ',
'いとう'
];
この配列を五十音順に並び替える場合は、以下のように記述します。
$collator = new Collator('ja_JP');
usort($names, function ($a, $b) use ($collator) {
$result = $collator->compare($a, $b);
if ($result === false) {
throw new RuntimeException(
'文字列の比較に失敗しました。'
);
}
return $result;
});
print_r($names);
実行結果は以下のとおりです。
Array
(
[0] => あおき
[1] => いとう
[2] => さとう
[3] => たなか
[4] => やまだ
)
Collatorクラスでは、指定したロケールに応じた文字列比較を行えます。
今回の例では、ja_JPを指定して日本語の照合規則を使用しています。
なお、Collator::compare()は比較に失敗した場合にfalseを返すことがあります。
そのため、サンプルコードではfalseが返された場合に例外を発生させています。
また、CollatorはICUの照合規則に基づいて比較するため、すべての文字列が必ずしも辞書や人名録と同じ順序になるわけではありません。
Collatorを使用するには、PHPのintl拡張機能が有効になっている必要があります。
漢字の名前を五十音順に並び替える
漢字の名前を読み仮名の五十音順に並び替える場合は、ふりがなを別途用意する方法が確実です。
例えば、以下のようなユーザーデータを考えます。
$users = [
['name' => '田中', 'kana' => 'たなか'],
['name' => '佐藤', 'kana' => 'さとう'],
['name' => '青木', 'kana' => 'あおき']
];
この場合、nameではなくkanaを基準に並び替えます。
$collator = new Collator('ja_JP');
usort($users, function ($a, $b) use ($collator) {
$result = $collator->compare(
$a['kana'],
$b['kana']
);
if ($result === false) {
throw new RuntimeException(
'文字列の比較に失敗しました。'
);
}
return $result;
});
この方法なら、漢字の読み方に基づいて並び替えられます。
会員一覧や店舗一覧、顧客管理システムなどで活用できる方法です。
usort()とほかのソート関数の違い
PHPには、usort()以外にもさまざまなソート関数が用意されています。
用途に応じて使い分けることで、より簡潔でわかりやすいコードを記述できます。
主なソート関数は、以下のとおりです。
| 関数 | 並び替え方法 | キーの扱い |
|---|---|---|
sort() | 値を昇順に並び替える | キーを振り直す |
rsort() | 値を降順に並び替える | キーを振り直す |
asort() | 値を昇順に並び替える | キーを維持する |
arsort() | 値を降順に並び替える | キーを維持する |
ksort() | キーを昇順に並び替える | キーを維持する |
krsort() | キーを降順に並び替える | キーを維持する |
usort() | 独自の比較関数で値を並び替える | キーを振り直す |
uasort() | 独自の比較関数で値を並び替える | キーを維持する |
uksort() | 独自の比較関数でキーを並び替える | キーを維持する |
それぞれの違いを理解しておくと、配列の構造や並び替え条件に合わせて適切な関数を選択できます。
sort()とusort()の違い
sort()は、配列の値をPHPの標準的な比較ルールに従って昇順に並び替える関数です。
例えば、数値の配列を昇順に並び替えるだけなら、以下のコードで実現できます。
$numbers = [5, 3, 8, 1];
sort($numbers);
print_r($numbers);
一方、独自の条件を指定して並び替えたい場合は、usort()が適しています。
例えば、数値の絶対値が小さい順に並び替える場合です。
$numbers = [-10, 5, -3, 8];
usort($numbers, function ($a, $b) {
return abs($a) <=> abs($b);
});
print_r($numbers);
実行結果は以下のとおりです。
Array
(
[0] => -3
[1] => 5
[2] => 8
[3] => -10
)
このように、単純な昇順・降順であればsort()やrsort()を使用し、独自の比較ルールが必要な場合はusort()を使用するとよいでしょう。
usort()とuasort()の違い
usort()とuasort()の大きな違いは、配列のキーを維持するかどうかです。
usort()は、既存のキーを削除して、0から始まる連続した整数キーを新しく割り当てます。
一方、uasort()は、元のキーと値の対応関係を維持したまま並び替えます。
例えば、以下の連想配列を考えます。
$scores = [
'tanaka' => 80,
'sato' => 95,
'suzuki' => 70
];
usort()を使用すると、以下のようになります。
usort($scores, fn($a, $b) => $b <=> $a);
print_r($scores);
実行結果は以下のとおりです。
Array
(
[0] => 95
[1] => 80
[2] => 70
)
元のキーであるtanaka、sato、suzukiが失われています。
一方、uasort()を使用すると、以下のようになります。
$scores = [
'tanaka' => 80,
'sato' => 95,
'suzuki' => 70
];
uasort($scores, fn($a, $b) => $b <=> $a);
print_r($scores);
実行結果は以下のとおりです。
Array
(
[sato] => 95
[tanaka] => 80
[suzuki] => 70
)
このように、キーを維持したまま値を並び替えられます。
商品IDやユーザーIDなどをキーにしている場合は、uasort()の使用を検討してください。
usort()とarray_multisort()の違い
array_multisort()も、配列の並び替えに使用できるPHPの関数です。
複数の配列や列を基準にして並び替える場合に便利です。
例えば、以下の商品データを価格順に並び替えます。
$products = [
['name' => '商品A', 'price' => 3000],
['name' => '商品B', 'price' => 1000],
['name' => '商品C', 'price' => 2000]
];
array_multisort()を使用する場合は、以下のように記述できます。
$prices = array_column($products, 'price');
array_multisort(
$prices,
SORT_ASC,
SORT_NUMERIC,
$products
);
print_r($products);
このコードでは、商品価格を取り出して並び替えの基準にしています。
SORT_ASCは昇順、SORT_NUMERICは数値として比較することを指定する定数です。
usort()は比較関数を自由に定義できるため、複雑な条件を指定する場合に適しています。
一方、array_multisort()は、複数の列を指定して定型的な並び替えを行う場合に便利です。
usort()を使用する際の注意点
usort()は便利な関数ですが、使用する際にはいくつかの注意点があります。
特に、元の配列の変更やキーの再割り当て、比較関数の戻り値については理解しておきましょう。
元の配列が直接変更される
usort()は、引数に指定した配列を直接並び替えます。
$numbers = [3, 1, 2];
usort($numbers, fn($a, $b) => $a <=> $b);
実行後の$numbersは、以下の状態になります。
[1, 2, 3]
並び替え前のデータが必要な場合は、元の配列をコピーしてから処理してください。
配列のキーが振り直される
usort()では、既存のキーがすべて削除され、0から始まる整数キーが新しく割り当てられます。
数値キーだけでなく、文字列キーも保持されません。
例えば、以下のコードを実行します。
$data = [
10 => 'banana',
20 => 'apple',
30 => 'orange'
];
usort($data, fn($a, $b) => strcmp($a, $b));
print_r($data);
実行結果は以下のとおりです。
Array
(
[0] => apple
[1] => banana
[2] => orange
)
元のキーである10、20、30は失われています。
キーを保持したい場合は、uasort()を使用してください。
比較関数では整数を返す
usort()の比較関数では、負の整数、0、正の整数のいずれかを返す必要があります。
以下のように、真偽値を返す書き方は避けましょう。
// 非推奨
usort($numbers, function ($a, $b) {
return $a > $b;
});
このコードでは、$aが$bより小さい場合と、等しい場合の両方でfalseが返されます。
そのため、要素の大小関係を正しく表現できません。
正しくは、以下のように記述します。
usort($numbers, function ($a, $b) {
return $a <=> $b;
});
また、比較結果を単純に引き算で返す方法にも注意が必要です。
// 値によっては不適切
return $a - $b;
例えば、小数の差が0.5の場合、比較関数の戻り値として整数に変換されると0になってしまいます。
整数の範囲によっても、引き算では意図しない結果になる可能性があります。
基本的には、宇宙船演算子を使用すると安全でわかりやすくなります。
PHP 8.0以降では安定ソートが保証されている
PHP 8.0以降では、usort()を含むソート関数の安定性が保証されています。
安定ソートとは、比較結果が等しい要素について、元の並び順が維持されることです。
例えば、以下の商品データを考えます。
$products = [
['name' => '商品A', 'price' => 1000],
['name' => '商品B', 'price' => 2000],
['name' => '商品C', 'price' => 1000]
];
価格順に並び替えます。
usort($products, fn($a, $b) =>
$a['price'] <=> $b['price']
);
PHP 8.0以降では、価格が同じ商品Aと商品Cの並び順が維持されます。
| 商品名 | 価格 |
|---|---|
| 商品A | 1,000円 |
| 商品C | 1,000円 |
| 商品B | 2,000円 |
PHP 7系以前では、比較結果が同じ要素の順序は保証されていません。
古いPHP環境で同順位の要素の順序を維持したい場合は、元の位置を比較条件に加えるなどの対応が必要です。
比較対象のデータ型を統一する
usort()で数値を比較する場合は、データ型を統一しておくことが重要です。
例えば、以下の配列には整数と数値文字列が混在しています。
$numbers = [10, '20', 5, '100'];
PHPの比較演算子には型変換のルールがあるため、異なるデータ型が混在すると、意図しない比較結果になる可能性があります。
整数として比較したい場合は、以下のように型変換できます。
usort($numbers, function ($a, $b) {
return (int)$a <=> (int)$b;
});
ただし、この方法はすべての要素を整数として扱える場合に限ります。
小数や不正な文字列などが含まれる場合は、適切なバリデーションや型変換が必要です。
実際のシステムでは、ソート前にデータ型を整えておくとよいでしょう。
大量のデータを並び替える場合は処理速度に注意する
usort()は、PHPのメモリ上にある配列を並び替える関数です。
一般的な比較ソートの計算量は、おおむねO(n log n)です。
ただし、比較関数の中で時間のかかる処理を実行すると、全体の処理速度が低下する可能性があります。
例えば、比較関数が呼び出されるたびにデータベースへ問い合わせるような処理は避けるべきです。
大量の商品データや記事データをデータベースから取得する場合は、SQLのORDER BYを使用する方法もあります。
SELECT *
FROM products
ORDER BY price ASC;
この方法なら、データベース側で価格の安い順に並び替えられます。
特に、ページネーションを行う場合は、データベース側で並び替えてから必要な件数だけを取得する方法が一般的です。
usort()を使った商品一覧の並び替え実装例
ここでは、実際のWebサイトを想定して、商品一覧の並び替え機能を実装する方法を紹介します。
ECサイトでは、価格順や人気順、新着順など、複数の条件で商品を並び替える機能がよく使用されます。
usort()を使用すれば、これらの条件を切り替える処理を実装できます。
商品データを用意する
まずは、以下の商品データを用意します。
$products = [
[
'id' => 1,
'name' => '商品A',
'price' => 3000,
'popularity' => 80,
'created_at' => '2026-01-10'
],
[
'id' => 2,
'name' => '商品B',
'price' => 1500,
'popularity' => 95,
'created_at' => '2026-03-15'
],
[
'id' => 3,
'name' => '商品C',
'price' => 5000,
'popularity' => 70,
'created_at' => '2026-02-20'
]
];
商品データには、商品ID、商品名、価格、人気度、登録日を設定しています。
今回は、以下の4種類の並び替えを実装します。
- 新着順
- 価格が安い順
- 価格が高い順
- 人気順
GETパラメータから並び替え条件を取得する
並び替え条件は、URLのクエリパラメータで指定します。
例えば、以下のようなURLです。
/products.php?sort=newest
/products.php?sort=price_asc
/products.php?sort=price_desc
/products.php?sort=popular
PHPでは、$_GETを使用してクエリパラメータを取得できます。
$sort = $_GET['sort'] ?? 'newest';
このコードでは、sortパラメータが指定されていない場合にnewestを使用します。
ただし、GETパラメータには想定外の値が指定される可能性があります。
そのため、実際のシステムでは、使用できる条件をあらかじめ定義しておきましょう。
$sortOptions = [
'newest' => '新着順',
'price_asc' => '価格が安い順',
'price_desc' => '価格が高い順',
'popular' => '人気順'
];
$sort = $_GET['sort'] ?? 'newest';
if (!is_string($sort) || !isset($sortOptions[$sort])) {
$sort = 'newest';
}
このようにすることで、未対応の値が指定された場合は新着順に戻せます。
並び替え条件に応じてusort()を実行する
取得した並び替え条件に応じて、usort()の比較関数を切り替えます。
switch ($sort) {
case 'price_asc':
// 価格が安い順
usort($products, fn($a, $b) =>
$a['price'] <=> $b['price']
);
break;
case 'price_desc':
// 価格が高い順
usort($products, fn($a, $b) =>
$b['price'] <=> $a['price']
);
break;
case 'popular':
// 人気順
usort($products, fn($a, $b) =>
$b['popularity'] <=> $a['popularity']
);
break;
case 'newest':
default:
// 新着順
usort($products, fn($a, $b) =>
strcmp($b['created_at'], $a['created_at'])
);
break;
}
これにより、URLで指定された条件に応じて商品データを並び替えられます。
なお、created_atはすべて有効なYYYY-MM-DD形式の文字列で統一されていることを前提としています。
また、同じ価格や人気度の商品が複数存在する場合に一定の順序で表示したいときは、商品IDなどを第2の比較条件として追加するとよいでしょう。
HTMLで商品一覧を表示する
並び替えた商品データは、foreachを使用してHTMLに出力できます。
<?php foreach ($products as $product): ?>
<div class="product">
<h3>
<?= htmlspecialchars(
$product['name'],
ENT_QUOTES,
'UTF-8'
) ?>
</h3>
<p>
価格:
<?= number_format($product['price']) ?>円
</p>
</div>
<?php endforeach; ?>
商品名を出力する際には、htmlspecialchars()を使用してHTMLエスケープしています。
これにより、商品名にHTMLの特殊文字が含まれていても、意図しないHTMLとして解釈されることを防げます。
HTMLのセレクトボックスで並び替えを切り替える
ユーザーが並び替え条件を選択できるように、HTMLのselect要素を設置します。
<form method="get">
<select name="sort">
<?php foreach ($sortOptions as $value => $label): ?>
<option
value="<?= htmlspecialchars($value, ENT_QUOTES, 'UTF-8') ?>"
<?= $sort === $value ? 'selected' : '' ?>
>
<?= htmlspecialchars($label, ENT_QUOTES, 'UTF-8') ?>
</option>
<?php endforeach; ?>
</select>
<button type="submit">
並び替える
</button>
</form>
このコードでは、現在の並び替え条件に応じてselected属性を設定しています。
そのため、並び替え後にページを再読み込みしても、選択した条件がセレクトボックスに表示されます。
これらの処理を組み合わせることで、商品一覧の並び替え機能を実装できます。
なお、検索条件やページ番号など、ほかのGETパラメータも使用する場合は、それらを保持する処理を追加する必要があります。
また、大量の商品を扱う場合は、PHPで全件取得して並び替えるよりも、データベース側で並び替える構成が適していることがあります。
PHPのusort()に関するよくある質問
最後に、PHPのusort()に関するよくある質問を紹介します。
usort()で降順に並び替えるには?
数値を降順に並び替える場合は、比較関数で$b <=> $aを返します。
usort($array, fn($a, $b) => $b <=> $a);
昇順の場合は$a <=> $bを使用します。
usort()は連想配列にも使用できる?
はい、連想配列にも使用できます。
ただし、usort()を使用すると既存のキーが削除され、0から始まる整数キーが新しく割り当てられます。
元のキーを維持したい場合は、uasort()を使用してください。
usort()で配列の特定のキーを基準に並び替えられる?
はい、可能です。
例えば、商品の価格を基準に並び替える場合は、以下のように記述します。
usort($products, fn($a, $b) =>
$a['price'] <=> $b['price']
);
比較するキーを変更することで、年齢、価格、点数など、さまざまな項目を基準に並び替えられます。
usort()で空の配列を並び替えるとどうなる?
空の配列に対してusort()を実行しても、配列の内容は変わりません。
$array = [];
usort($array, fn($a, $b) => $a <=> $b);
print_r($array);
実行結果は以下のとおりです。
Array
(
)
空の配列では比較する要素が存在しないため、比較関数は呼び出されません。
usort()でnullを最後に並び替えるには?
nullが含まれる配列を並び替える場合は、nullをどの位置に配置するかを明示的に指定するとよいでしょう。
例えば、nullを最後に配置し、それ以外の数値を昇順に並び替える場合は、以下のように記述します。
$numbers = [10, null, 30, 5, null, 20];
usort($numbers, function ($a, $b) {
if ($a === null && $b === null) {
return 0;
}
if ($a === null) {
return 1;
}
if ($b === null) {
return -1;
}
return $a <=> $b;
});
print_r($numbers);
実行後の配列は、以下のようになります。
[5, 10, 20, 30, null, null]
このように、比較関数の中でnullを特別に処理することで、意図した位置に配置できます。
usort()とsort()はどちらを使用すべき?
単純に数値や文字列を昇順に並び替えるだけなら、sort()で十分です。
一方、独自の条件を指定したい場合や、多次元配列の特定の項目を基準に並び替えたい場合は、usort()が適しています。
処理内容に合わせて使い分けましょう。
まとめ|PHPのusort()を使えば配列を自由な条件で並び替えられる
PHPのusort()は、独自の比較関数を使用して配列を並び替えられる便利な関数です。
数値や文字列の昇順・降順だけでなく、多次元配列の特定の項目を基準にした並び替えや、複数条件による並び替えにも対応しています。
特に覚えておきたいのは、以下の基本的な書き方です。
数値を昇順に並び替える場合
usort($array, fn($a, $b) => $a <=> $b);
数値を降順に並び替える場合
usort($array, fn($a, $b) => $b <=> $a);
多次元配列を価格の安い順に並び替える場合
usort($products, fn($a, $b) =>
$a['price'] <=> $b['price']
);
複数条件で並び替える場合
usort($users, fn($a, $b) =>
($a['age'] <=> $b['age'])
?: ($b['score'] <=> $a['score'])
);
これらの基本形を理解すれば、さまざまな並び替え処理に応用できます。
ただし、usort()は元の配列を直接変更し、既存のキーを振り直す点に注意が必要です。
キーを維持したい場合はuasort()を使用し、単純な並び替えであればsort()やrsort()なども検討しましょう。
また、大量のデータを扱う場合は、SQLのORDER BYを使用するなど、処理内容に応じた方法を選択することも重要です。
usort()の比較関数の仕組みを理解して、商品一覧や記事一覧、ランキングなど、さまざまなWebサイトの開発に活用してみてください。
以上、PHPのusort関数の使い方や配列の並び替えについてでした。
最後までお読みいただき、ありがとうございました。










