こんにちは!今回は、PHPの標準関数であるsort()について詳しく解説していきます。配列を昇順に並び替える最も基本的なソート関数です!
sort関数とは?
sort()関数は、配列を値の昇順に並び替える関数です。
元の配列を直接変更し(破壊的操作)、インデックスは0から振り直されます。数値、文字列、その他の型を自動的に判断してソートします!
基本的な構文
sort(array &$array, int $flags = SORT_REGULAR): bool
- $array: ソートする配列(参照渡し)
- $flags: ソート方法を指定するフラグ(オプション)
- 戻り値: 成功時は
true、失敗時はfalse
ソートフラグ
SORT_REGULAR // 型を変換せずに比較(デフォルト)
SORT_NUMERIC // 数値として比較
SORT_STRING // 文字列として比較
SORT_LOCALE_STRING // 現在のロケールに基づいて文字列として比較
SORT_NATURAL // 自然順ソート(natsort()と同じ)
SORT_FLAG_CASE // SORT_STRING | SORT_FLAG_CASE で大文字小文字を区別しない
基本的な使用例
数値の配列をソート
// 数値の配列
$numbers = [5, 2, 8, 1, 9, 3];
sort($numbers);
print_r($numbers);
/*
Array (
[0] => 1
[1] => 2
[2] => 3
[3] => 5
[4] => 8
[5] => 9
)
*/
文字列の配列をソート
// 文字列の配列
$fruits = ['orange', 'apple', 'banana', 'grape'];
sort($fruits);
print_r($fruits);
/*
Array (
[0] => apple
[1] => banana
[2] => grape
[3] => orange
)
*/
インデックスの振り直し
// 連想配列のキーは失われる
$data = [
'c' => 3,
'a' => 1,
'b' => 2
];
sort($data);
print_r($data);
/*
Array (
[0] => 1
[1] => 2
[2] => 3
)
*/
// キー(c, a, b)は失われて0から振り直される
ソートフラグの使用
// 数値として比較
$mixed = ['10', '2', '1', '20'];
sort($mixed, SORT_NUMERIC);
print_r($mixed);
// Array ( [0] => 1 [1] => 2 [2] => 10 [3] => 20 )
// 文字列として比較
$mixed = ['10', '2', '1', '20'];
sort($mixed, SORT_STRING);
print_r($mixed);
// Array ( [0] => 1 [1] => 10 [2] => 2 [3] => 20 )
// 自然順ソート
$files = ['file10.txt', 'file2.txt', 'file1.txt', 'file20.txt'];
sort($files, SORT_NATURAL);
print_r($files);
// Array ( [0] => file1.txt [1] => file2.txt [2] => file10.txt [3] => file20.txt )
大文字小文字を区別しないソート
$words = ['Apple', 'banana', 'Cherry', 'apple'];
sort($words, SORT_STRING | SORT_FLAG_CASE);
print_r($words);
/*
Array (
[0] => Apple
[1] => apple
[2] => banana
[3] => Cherry
)
*/
実践的な使用例
例1: データソーター
class DataSorter {
/**
* 数値配列を昇順ソート
*/
public static function sortNumbers($array) {
sort($array, SORT_NUMERIC);
return $array;
}
/**
* 数値配列を降順ソート
*/
public static function sortNumbersDescending($array) {
rsort($array, SORT_NUMERIC);
return $array;
}
/**
* 文字列配列をソート
*/
public static function sortStrings($array, $caseInsensitive = false) {
$flags = $caseInsensitive ?
(SORT_STRING | SORT_FLAG_CASE) :
SORT_STRING;
sort($array, $flags);
return $array;
}
/**
* 自然順ソート
*/
public static function sortNatural($array) {
sort($array, SORT_NATURAL);
return $array;
}
/**
* 混合型配列をソート
*/
public static function sortMixed($array) {
sort($array, SORT_REGULAR);
return $array;
}
/**
* ユニーク値を抽出してソート
*/
public static function uniqueAndSort($array) {
$unique = array_unique($array);
sort($unique);
return $unique;
}
/**
* 配列をソートして最小値・最大値を取得
*/
public static function getMinMax($array) {
$sorted = self::sortNumbers($array);
return [
'min' => $sorted[0] ?? null,
'max' => $sorted[count($sorted) - 1] ?? null,
'sorted' => $sorted
];
}
/**
* 中央値を取得(ソート後)
*/
public static function getMedian($array) {
$sorted = self::sortNumbers($array);
$count = count($sorted);
if ($count === 0) {
return null;
}
$middle = floor($count / 2);
if ($count % 2 === 0) {
// 偶数の場合は中央2つの平均
return ($sorted[$middle - 1] + $sorted[$middle]) / 2;
} else {
// 奇数の場合は中央の値
return $sorted[$middle];
}
}
}
// 使用例
echo "=== データソート ===\n";
// 数値ソート
$numbers = [5, 2, 8, 1, 9, 3, 7, 4, 6];
echo "元の配列: " . implode(', ', $numbers) . "\n";
echo "昇順: " . implode(', ', DataSorter::sortNumbers($numbers)) . "\n";
echo "降順: " . implode(', ', DataSorter::sortNumbersDescending($numbers)) . "\n";
// 文字列ソート
echo "\n=== 文字列ソート ===\n";
$words = ['banana', 'Apple', 'cherry', 'apple'];
echo "元の配列: " . implode(', ', $words) . "\n";
echo "通常: " . implode(', ', DataSorter::sortStrings($words)) . "\n";
echo "大小無視: " . implode(', ', DataSorter::sortStrings($words, true)) . "\n";
// 自然順ソート
echo "\n=== 自然順ソート ===\n";
$files = ['file10.txt', 'file2.txt', 'file1.txt', 'file20.txt'];
echo "通常ソート: " . implode(', ', DataSorter::sortStrings($files)) . "\n";
echo "自然順: " . implode(', ', DataSorter::sortNatural($files)) . "\n";
// 最小値・最大値
echo "\n=== 最小値・最大値 ===\n";
$data = [45, 23, 89, 12, 67, 34];
$minMax = DataSorter::getMinMax($data);
echo "最小値: {$minMax['min']}\n";
echo "最大値: {$minMax['max']}\n";
// 中央値
echo "\n=== 中央値 ===\n";
$values = [1, 3, 5, 7, 9];
echo "中央値: " . DataSorter::getMedian($values) . "\n";
例2: 成績処理システム
class GradeProcessor {
/**
* 成績を昇順にソート
*/
public static function sortGrades($grades) {
sort($grades, SORT_NUMERIC);
return $grades;
}
/**
* ランキングを生成
*/
public static function generateRanking($students) {
// 成績のみを抽出
$scores = [];
foreach ($students as $student) {
$scores[] = $student['score'];
}
// 降順にソート
rsort($scores, SORT_NUMERIC);
// ランキングマップを作成
$ranking = [];
$currentRank = 1;
foreach ($scores as $index => $score) {
if (!isset($ranking[$score])) {
$ranking[$score] = $currentRank;
}
$currentRank++;
}
// 学生データにランキングを追加
foreach ($students as &$student) {
$student['rank'] = $ranking[$student['score']];
}
return $students;
}
/**
* 成績を分類
*/
public static function classifyGrades($grades) {
$sorted = self::sortGrades($grades);
return [
'excellent' => array_filter($sorted, fn($g) => $g >= 90),
'good' => array_filter($sorted, fn($g) => $g >= 70 && $g < 90),
'average' => array_filter($sorted, fn($g) => $g >= 50 && $g < 70),
'poor' => array_filter($sorted, fn($g) => $g < 50)
];
}
/**
* 統計情報を取得
*/
public static function getStatistics($grades) {
$sorted = self::sortGrades($grades);
$count = count($sorted);
if ($count === 0) {
return null;
}
return [
'count' => $count,
'min' => $sorted[0],
'max' => $sorted[$count - 1],
'average' => array_sum($sorted) / $count,
'median' => DataSorter::getMedian($sorted),
'sorted' => $sorted
];
}
/**
* 上位N件を取得
*/
public static function getTopN($grades, $n) {
$sorted = self::sortGrades($grades);
return array_slice(array_reverse($sorted), 0, $n);
}
/**
* 下位N件を取得
*/
public static function getBottomN($grades, $n) {
$sorted = self::sortGrades($grades);
return array_slice($sorted, 0, $n);
}
}
// 使用例
echo "=== 成績処理システム ===\n";
$grades = [85, 92, 78, 65, 88, 95, 72, 80, 90, 68];
// 統計情報
$stats = GradeProcessor::getStatistics($grades);
echo "統計情報:\n";
echo " 件数: {$stats['count']}\n";
echo " 最低点: {$stats['min']}\n";
echo " 最高点: {$stats['max']}\n";
echo " 平均点: " . round($stats['average'], 2) . "\n";
echo " 中央値: {$stats['median']}\n";
// 成績分類
echo "\n=== 成績分類 ===\n";
$classified = GradeProcessor::classifyGrades($grades);
foreach ($classified as $category => $scores) {
echo "{$category}: " . implode(', ', $scores) . "\n";
}
// 上位・下位
echo "\n=== 上位・下位 ===\n";
echo "上位3件: " . implode(', ', GradeProcessor::getTopN($grades, 3)) . "\n";
echo "下位3件: " . implode(', ', GradeProcessor::getBottomN($grades, 3)) . "\n";
// ランキング
echo "\n=== ランキング ===\n";
$students = [
['name' => 'Alice', 'score' => 85],
['name' => 'Bob', 'score' => 92],
['name' => 'Charlie', 'score' => 78],
['name' => 'David', 'score' => 92],
['name' => 'Eve', 'score' => 88]
];
$ranked = GradeProcessor::generateRanking($students);
foreach ($ranked as $student) {
echo "{$student['rank']}位: {$student['name']} ({$student['score']}点)\n";
}
例3: 在庫管理システム
class InventoryManager {
/**
* 在庫数でソート
*/
public static function sortByQuantity($items) {
$quantities = array_column($items, 'quantity');
array_multisort($quantities, SORT_ASC, $items);
return $items;
}
/**
* 価格でソート
*/
public static function sortByPrice($items) {
$prices = array_column($items, 'price');
array_multisort($prices, SORT_ASC, $items);
return $items;
}
/**
* 在庫切れ・少量在庫を抽出
*/
public static function getLowStock($items, $threshold = 10) {
$lowStock = array_filter($items, function($item) use ($threshold) {
return $item['quantity'] <= $threshold;
});
return self::sortByQuantity(array_values($lowStock));
}
/**
* 商品名でソート
*/
public static function sortByName($items) {
$names = array_column($items, 'name');
array_multisort($names, SORT_ASC, SORT_STRING, $items);
return $items;
}
/**
* カテゴリ別にグループ化してソート
*/
public static function groupByCategory($items) {
$grouped = [];
foreach ($items as $item) {
$category = $item['category'];
if (!isset($grouped[$category])) {
$grouped[$category] = [];
}
$grouped[$category][] = $item;
}
// カテゴリ名でソート
ksort($grouped);
// 各カテゴリ内を商品名でソート
foreach ($grouped as &$categoryItems) {
$categoryItems = self::sortByName($categoryItems);
}
return $grouped;
}
/**
* 在庫総額を計算
*/
public static function calculateTotalValue($items) {
$total = 0;
foreach ($items as $item) {
$total += $item['price'] * $item['quantity'];
}
return $total;
}
}
// 使用例
echo "=== 在庫管理システム ===\n";
$inventory = [
['name' => 'りんご', 'category' => '果物', 'price' => 100, 'quantity' => 50],
['name' => 'バナナ', 'category' => '果物', 'price' => 80, 'quantity' => 5],
['name' => 'にんじん', 'category' => '野菜', 'price' => 60, 'quantity' => 30],
['name' => 'じゃがいも', 'category' => '野菜', 'price' => 50, 'quantity' => 3],
['name' => 'トマト', 'category' => '野菜', 'price' => 120, 'quantity' => 25]
];
// 在庫数でソート
echo "在庫数順:\n";
$sorted = InventoryManager::sortByQuantity($inventory);
foreach ($sorted as $item) {
echo " {$item['name']}: {$item['quantity']}個\n";
}
// 価格でソート
echo "\n価格順:\n";
$sorted = InventoryManager::sortByPrice($inventory);
foreach ($sorted as $item) {
echo " {$item['name']}: {$item['price']}円\n";
}
// 在庫少量商品
echo "\n在庫少量商品(10個以下):\n";
$lowStock = InventoryManager::getLowStock($inventory, 10);
foreach ($lowStock as $item) {
echo " {$item['name']}: {$item['quantity']}個(要補充)\n";
}
// カテゴリ別
echo "\nカテゴリ別:\n";
$grouped = InventoryManager::groupByCategory($inventory);
foreach ($grouped as $category => $items) {
echo "\n{$category}:\n";
foreach ($items as $item) {
echo " - {$item['name']} ({$item['quantity']}個, {$item['price']}円)\n";
}
}
// 在庫総額
echo "\n在庫総額: " . number_format(InventoryManager::calculateTotalValue($inventory)) . "円\n";
例4: ファイル管理システム
class FileManager {
/**
* ファイル名をソート
*/
public static function sortByName($files) {
sort($files, SORT_STRING);
return $files;
}
/**
* ファイル名を自然順でソート
*/
public static function sortNatural($files) {
sort($files, SORT_NATURAL);
return $files;
}
/**
* ファイルサイズでソート
*/
public static function sortBySize($files) {
$sizes = [];
foreach ($files as $file) {
$sizes[] = file_exists($file) ? filesize($file) : 0;
}
array_multisort($sizes, SORT_ASC, $files);
return $files;
}
/**
* 更新日時でソート
*/
public static function sortByModifiedTime($files) {
$times = [];
foreach ($files as $file) {
$times[] = file_exists($file) ? filemtime($file) : 0;
}
array_multisort($times, SORT_ASC, $files);
return $files;
}
/**
* 拡張子でグループ化
*/
public static function groupByExtension($files) {
$grouped = [];
foreach ($files as $file) {
$ext = pathinfo($file, PATHINFO_EXTENSION);
$ext = $ext ?: 'no_extension';
if (!isset($grouped[$ext])) {
$grouped[$ext] = [];
}
$grouped[$ext][] = $file;
}
// 拡張子でソート
ksort($grouped);
// 各グループ内をファイル名でソート
foreach ($grouped as &$group) {
$group = self::sortNatural($group);
}
return $grouped;
}
/**
* ディレクトリ内のファイルをソート
*/
public static function listSorted($directory, $sortBy = 'name') {
$files = glob($directory . '/*');
switch ($sortBy) {
case 'size':
return self::sortBySize($files);
case 'date':
return self::sortByModifiedTime($files);
case 'natural':
return self::sortNatural($files);
default:
return self::sortByName($files);
}
}
}
// 使用例
echo "=== ファイル管理システム ===\n";
$files = [
'file10.txt',
'file2.txt',
'file1.txt',
'file20.txt',
'document.pdf',
'image.jpg',
'script.php'
];
// 通常のソート
echo "通常ソート:\n";
$sorted = FileManager::sortByName($files);
foreach ($sorted as $file) {
echo " {$file}\n";
}
// 自然順ソート
echo "\n自然順ソート:\n";
$sorted = FileManager::sortNatural($files);
foreach ($sorted as $file) {
echo " {$file}\n";
}
// 拡張子でグループ化
echo "\n拡張子別:\n";
$grouped = FileManager::groupByExtension($files);
foreach ($grouped as $ext => $fileList) {
echo "\n.{$ext}:\n";
foreach ($fileList as $file) {
echo " - {$file}\n";
}
}
例5: タグ・キーワード管理
class TagManager {
/**
* タグをソート(重複除去)
*/
public static function sortTags($tags, $caseInsensitive = true) {
// 重複除去
$tags = array_unique($tags);
// ソート
if ($caseInsensitive) {
sort($tags, SORT_STRING | SORT_FLAG_CASE);
} else {
sort($tags, SORT_STRING);
}
return array_values($tags);
}
/**
* タグを頻度順にソート
*/
public static function sortByFrequency($tags) {
$frequency = array_count_values($tags);
arsort($frequency);
return array_keys($frequency);
}
/**
* タグを正規化してソート
*/
public static function normalizeAndSort($tags) {
// 正規化(小文字化、トリム)
$normalized = array_map(function($tag) {
return strtolower(trim($tag));
}, $tags);
// 重複除去とソート
return self::sortTags($normalized);
}
/**
* 人気タグを取得
*/
public static function getPopularTags($tags, $limit = 10) {
$sorted = self::sortByFrequency($tags);
return array_slice($sorted, 0, $limit);
}
/**
* タグクラウド用データを生成
*/
public static function generateTagCloud($tags) {
$frequency = array_count_values($tags);
$sorted = self::sortTags(array_keys($frequency));
$cloud = [];
foreach ($sorted as $tag) {
$cloud[] = [
'tag' => $tag,
'count' => $frequency[$tag],
'weight' => self::calculateWeight($frequency[$tag], $frequency)
];
}
return $cloud;
}
/**
* タグの重み(サイズ)を計算
*/
private static function calculateWeight($count, $allCounts) {
$min = min($allCounts);
$max = max($allCounts);
if ($max === $min) {
return 50;
}
// 10-100の範囲に正規化
return 10 + (($count - $min) / ($max - $min)) * 90;
}
}
// 使用例
echo "=== タグ管理 ===\n";
$tags = [
'PHP', 'JavaScript', 'php', 'Python', 'PHP',
'JavaScript', 'Ruby', 'Go', 'PHP', 'Java',
'JavaScript', 'PHP', 'TypeScript'
];
// タグをソート
echo "ソート済みタグ:\n";
$sorted = TagManager::sortTags($tags);
echo " " . implode(', ', $sorted) . "\n";
// 頻度順
echo "\n頻度順:\n";
$byFrequency = TagManager::sortByFrequency($tags);
foreach ($byFrequency as $tag) {
$count = count(array_filter($tags, fn($t) => strtolower($t) === strtolower($tag)));
echo " {$tag}: {$count}回\n";
}
// 人気タグ
echo "\n人気タグ(上位5件):\n";
$popular = TagManager::getPopularTags($tags, 5);
echo " " . implode(', ', $popular) . "\n";
// タグクラウド
echo "\nタグクラウドデータ:\n";
$cloud = TagManager::generateTagCloud($tags);
foreach ($cloud as $item) {
echo " {$item['tag']}: {$item['count']}回 (重み: " . round($item['weight']) . ")\n";
}
例6: 検索結果のソート
class SearchResultSorter {
/**
* スコアでソート
*/
public static function sortByRelevance($results) {
$scores = array_column($results, 'score');
array_multisort($scores, SORT_DESC, $results);
return $results;
}
/**
* 日付でソート(新しい順)
*/
public static function sortByDate($results) {
$dates = array_column($results, 'date');
array_multisort($dates, SORT_DESC, $results);
return $results;
}
/**
* タイトルでソート
*/
public static function sortByTitle($results) {
$titles = array_column($results, 'title');
array_multisort($titles, SORT_ASC, SORT_STRING, $results);
return $results;
}
/**
* 複合ソート(スコア→日付)
*/
public static function sortByRelevanceAndDate($results) {
$scores = array_column($results, 'score');
$dates = array_column($results, 'date');
array_multisort(
$scores, SORT_DESC,
$dates, SORT_DESC,
$results
);
return $results;
}
/**
* ページネーション用に分割
*/
public static function paginate($results, $page = 1, $perPage = 10) {
$offset = ($page - 1) * $perPage;
return [
'results' => array_slice($results, $offset, $perPage),
'total' => count($results),
'page' => $page,
'per_page' => $perPage,
'total_pages' => ceil(count($results) / $perPage)
];
}
}
// 使用例
echo "=== 検索結果ソート ===\n";
$searchResults = [
['title' => '記事A', 'score' => 0.9, 'date' => '2026-03-20'],
['title' => '記事B', 'score' => 0.7, 'date' => '2026-03-22'],
['title' => '記事C', 'score' => 0.9, 'date' => '2026-03-21'],
['title' => '記事D', 'score' => 0.5, 'date' => '2026-03-23'],
];
// 関連度順
echo "関連度順:\n";
$sorted = SearchResultSorter::sortByRelevance($searchResults);
foreach ($sorted as $result) {
echo " {$result['title']} (スコア: {$result['score']})\n";
}
// 日付順
echo "\n日付順(新しい順):\n";
$sorted = SearchResultSorter::sortByDate($searchResults);
foreach ($sorted as $result) {
echo " {$result['title']} ({$result['date']})\n";
}
// 複合ソート
echo "\n関連度→日付順:\n";
$sorted = SearchResultSorter::sortByRelevanceAndDate($searchResults);
foreach ($sorted as $result) {
echo " {$result['title']} (スコア: {$result['score']}, 日付: {$result['date']})\n";
}
他のソート関数との比較
$array = ['c' => 3, 'a' => 1, 'b' => 2];
// sort() - 値でソート、キーを失う
$sorted = $array;
sort($sorted);
print_r($sorted);
// Array ( [0] => 1 [1] => 2 [2] => 3 )
// asort() - 値でソート、キーを保持
$sorted = $array;
asort($sorted);
print_r($sorted);
// Array ( [a] => 1 [b] => 2 [c] => 3 )
// ksort() - キーでソート
$sorted = $array;
ksort($sorted);
print_r($sorted);
// Array ( [a] => 1 [b] => 2 [c] => 3 )
// rsort() - 降順ソート
$sorted = $array;
rsort($sorted);
print_r($sorted);
// Array ( [0] => 3 [1] => 2 [2] => 1 )
まとめ
sort()関数の特徴をまとめると:
できること:
- 配列を値の昇順にソート
- 数値・文字列・混合型に対応
- 様々なソートフラグで動作調整
推奨される使用場面:
- 単純な配列のソート
- 数値データの並び替え
- 文字列リストの整列
- ランキング生成
ソートフラグ:
SORT_REGULAR: デフォルトSORT_NUMERIC: 数値として比較SORT_STRING: 文字列として比較SORT_NATURAL: 自然順ソートSORT_FLAG_CASE: 大文字小文字無視
注意点:
- 元の配列を直接変更(破壊的)
- キーは0から振り直される
- 連想配列のキーは失われる
関連関数:
rsort(): 降順ソートasort(): キーを保持してソートksort(): キーでソートusort(): ユーザー定義関数でソートnatsort(): 自然順ソート
使い分け:
// 単純な配列のソート
sort($array);
// キーを保持
asort($array);
// 降順
rsort($array);
// 自然順
sort($array, SORT_NATURAL);
sort()は、PHPで最も基本的なソート関数です。配列を昇順に並び替える際は、この関数からスタートしましょう!
