PHP数组排序

数组排序是PHP中常见的操作之一。PHP提供了一系列强大的数组排序函数,可以对索引数组、关联数组和多维数组进行排序。本教程将详细介绍PHP中各种数组排序方法的使用技巧和实际应用场景。

PHP数组排序函数概述

PHP提供了多种数组排序函数,用于满足不同的排序需求:

函数 描述 适用数组类型 是否保留键值关联
sort() 按值升序排序 索引数组
rsort() 按值降序排序 索引数组
asort() 按值升序排序 关联数组
arsort() 按值降序排序 关联数组
ksort() 按键名升序排序 关联数组
krsort() 按键名降序排序 关联数组
usort() 使用用户自定义函数排序 索引数组
uasort() 使用用户自定义函数排序 关联数组
uksort() 使用用户自定义函数按键排序 关联数组
natsort() 使用自然排序算法排序 索引/关联数组
natcasesort() 使用自然排序算法不区分大小写排序 索引/关联数组
shuffle() 随机打乱数组 索引/关联数组 否(索引数组)
array_multisort() 对多个数组或多维数组排序 多维数组

索引数组排序

索引数组是使用数字索引的数组,PHP提供了以下函数用于索引数组的排序:

1. sort()函数

sort()函数用于对索引数组进行升序排序。排序后,原数组的索引会被重新分配。

<?php
$numbers = array(4, 2, 8, 6, 1);
sort($numbers);

// 输出排序后的数组
echo "升序排序后的数组: ";
print_r($numbers);
// 输出: Array ( [0] => 1 [1] => 2 [2] => 4 [3] => 6 [4] => 8 )
?>

2. rsort()函数

rsort()函数用于对索引数组进行降序排序。排序后,原数组的索引会被重新分配。

<?php
$numbers = array(4, 2, 8, 6, 1);
rsort($numbers);

// 输出排序后的数组
echo "降序排序后的数组: ";
print_r($numbers);
// 输出: Array ( [0] => 8 [1] => 6 [2] => 4 [3] => 2 [4] => 1 )
?>

关联数组排序

关联数组是使用字符串键的数组,PHP提供了以下函数用于关联数组的排序:

1. asort()函数

asort()函数用于对关联数组按照值进行升序排序,同时保持键值之间的关联。

<?php
$ages = array("Peter" => 35, "Ben" => 37, "Joe" => 43);
asort($ages);

// 输出排序后的数组
echo "按值升序排序后的数组: ";
print_r($ages);
// 输出: Array ( [Peter] => 35 [Ben] => 37 [Joe] => 43 )
?>

2. arsort()函数

arsort()函数用于对关联数组按照值进行降序排序,同时保持键值之间的关联。

<?php
$ages = array("Peter" => 35, "Ben" => 37, "Joe" => 43);
arsort($ages);

// 输出排序后的数组
echo "按值降序排序后的数组: ";
print_r($ages);
// 输出: Array ( [Joe] => 43 [Ben] => 37 [Peter] => 35 )
?>

3. ksort()函数

ksort()函数用于对关联数组按照键名进行升序排序,同时保持键值之间的关联。

<?php
$ages = array("Peter" => 35, "Ben" => 37, "Joe" => 43);
ksort($ages);

// 输出排序后的数组
echo "按键名升序排序后的数组: ";
print_r($ages);
// 输出: Array ( [Ben] => 37 [Joe] => 43 [Peter] => 35 )
?>

4. krsort()函数

krsort()函数用于对关联数组按照键名进行降序排序,同时保持键值之间的关联。

<?php
$ages = array("Peter" => 35, "Ben" => 37, "Joe" => 43);
krsort($ages);

// 输出排序后的数组
echo "按键名降序排序后的数组: ";
print_r($ages);
// 输出: Array ( [Peter] => 35 [Joe] => 43 [Ben] => 37 )
?>

用户自定义排序

PHP允许使用用户自定义的比较函数来排序数组,这对于需要按照特定规则排序的情况非常有用。

1. usort()函数

usort()函数用于使用用户自定义的比较函数对索引数组进行排序。排序后,原数组的索引会被重新分配。

<?php
// 定义一个比较函数
function compare_numbers($a, $b) {
    if ($a == $b) {
        return 0;
    }
    return ($a < $b) ? -1 : 1;
}

$numbers = array(4, 2, 8, 6, 1);

// 使用用户自定义函数排序
usort($numbers, "compare_numbers");

// 输出排序后的数组
echo "使用用户自定义函数排序后的数组: ";
print_r($numbers);
// 输出: Array ( [0] => 1 [1] => 2 [2] => 4 [3] => 6 [4] => 8 )
?>

在PHP 7及以上版本中,可以使用太空船操作符(<=>)来简化比较函数:

<?php
// 使用太空船操作符的比较函数
function compare_numbers($a, $b) {
    return $a <=> $b;
}

$numbers = array(4, 2, 8, 6, 1);

// 使用用户自定义函数排序
usort($numbers, "compare_numbers");

// 输出排序后的数组
echo "使用太空船操作符排序后的数组: ";
print_r($numbers);
// 输出: Array ( [0] => 1 [1] => 2 [2] => 4 [3] => 6 [4] => 8 )
?>

还可以使用匿名函数:

<?php
$numbers = array(4, 2, 8, 6, 1);

// 使用匿名函数排序
usort($numbers, function($a, $b) {
    return $a <=> $b;
});

// 输出排序后的数组
echo "使用匿名函数排序后的数组: ";
print_r($numbers);
// 输出: Array ( [0] => 1 [1] => 2 [2] => 4 [3] => 6 [4] => 8 )
?>

2. uasort()函数

uasort()函数用于使用用户自定义的比较函数对关联数组进行排序,同时保持键值之间的关联。

<?php
$students = array(
    "John" => 85,
    "Mary" => 92,
    "Peter" => 78,
    "David" => 90
);

// 使用匿名函数按成绩降序排序
uasort($students, function($a, $b) {
    return $b <=> $a;
});

// 输出排序后的数组
echo "按成绩降序排序后的数组: ";
print_r($students);
// 输出: Array ( [Mary] => 92 [David] => 90 [John] => 85 [Peter] => 78 )
?>

3. uksort()函数

uksort()函数用于使用用户自定义的比较函数对关联数组按照键名进行排序,同时保持键值之间的关联。

<?php
$ages = array(
    "Peter" => 35,
    "Ben" => 37,
    "Joe" => 43,
    "Alice" => 28
);

// 使用匿名函数按键名长度排序
uksort($ages, function($a, $b) {
    return strlen($a) <=> strlen($b);
});

// 输出排序后的数组
echo "按键名长度排序后的数组: ";
print_r($ages);
// 输出: Array ( [Ben] => 37 [Joe] => 43 [Peter] => 35 [Alice] => 28 )
?>

多维数组排序

多维数组是包含一个或多个数组的数组,PHP提供了以下方法用于多维数组的排序:

1. 使用usort()函数排序多维数组

<?php
$products = array(
    array("name" => "iPhone", "price" => 999, "stock" => 20),
    array("name" => "Samsung", "price" => 899, "stock" => 15),
    array("name" => "Google Pixel", "price" => 799, "stock" => 10),
    array("name" => "OnePlus", "price" => 699, "stock" => 25)
);

// 按价格升序排序
usort($products, function($a, $b) {
    return $a["price"] <=> $b["price"];
});

// 输出排序后的数组
echo "按价格升序排序后的产品: ";
print_r($products);
/* 输出:
Array (
    [0] => Array ( [name] => OnePlus [price] => 699 [stock] => 25 )
    [1] => Array ( [name] => Google Pixel [price] => 799 [stock] => 10 )
    [2] => Array ( [name] => Samsung [price] => 899 [stock] => 15 )
    [3] => Array ( [name] => iPhone [price] => 999 [stock] => 20 )
)*/
?>

2. 使用array_multisort()函数排序多维数组

array_multisort()函数可以对多个数组或多维数组进行排序。它是PHP中功能最强大的排序函数之一。

<?php
$products = array(
    array("name" => "iPhone", "price" => 999, "stock" => 20),
    array("name" => "Samsung", "price" => 899, "stock" => 15),
    array("name" => "Google Pixel", "price" => 799, "stock" => 10),
    array("name" => "OnePlus", "price" => 699, "stock" => 25)
);

// 提取价格列
$prices = array_column($products, "price");

// 按价格升序排序多维数组
array_multisort($prices, SORT_ASC, $products);

// 输出排序后的数组
echo "使用array_multisort按价格升序排序后的产品: ";
print_r($products);
/* 输出:
Array (
    [0] => Array ( [name] => OnePlus [price] => 699 [stock] => 25 )
    [1] => Array ( [name] => Google Pixel [price] => 799 [stock] => 10 )
    [2] => Array ( [name] => Samsung [price] => 899 [stock] => 15 )
    [3] => Array ( [name] => iPhone [price] => 999 [stock] => 20 )
)*/
?>

3. 多字段排序

有时我们需要按照多个字段对多维数组进行排序。例如,先按类别排序,再按价格排序。

<?php
$products = array(
    array("category" => "手机", "name" => "iPhone", "price" => 999),
    array("category" => "平板", "name" => "iPad", "price" => 799),
    array("category" => "手机", "name" => "Samsung", "price" => 899),
    array("category" => "平板", "name" => "Galaxy Tab", "price" => 699)
);

// 先按类别升序排序,再按价格升序排序
usort($products, function($a, $b) {
    if ($a["category"] == $b["category"]) {
        return $a["price"] <=> $b["price"];
    }
    return $a["category"] <=> $b["category"];
});

// 输出排序后的数组
echo "按类别和价格排序后的产品: ";
print_r($products);
/* 输出:
Array (
    [0] => Array ( [category] => 平板 [name] => Galaxy Tab [price] => 699 )
    [1] => Array ( [category] => 平板 [name] => iPad [price] => 799 )
    [2] => Array ( [category] => 手机 [name] => Samsung [price] => 899 )
    [3] => Array ( [category] => 手机 [name] => iPhone [price] => 999 )
)*/
?>

自然排序

自然排序是一种按照人类习惯的方式进行排序的算法,它会考虑数字的实际大小而不仅仅是字符串比较。

1. natsort()函数

natsort()函数使用自然排序算法对数组进行排序,同时保持键值之间的关联。

<?php
$files = array("file1.txt", "file10.txt", "file2.txt", "file20.txt", "file3.txt");

// 使用自然排序
natsort($files);

// 输出排序后的数组
echo "自然排序后的文件列表: ";
print_r($files);
// 输出: Array ( [0] => file1.txt [2] => file2.txt [4] => file3.txt [1] => file10.txt [3] => file20.txt )

// 比较:普通排序
sort($files);
echo "普通排序后的文件列表: ";
print_r($files);
// 输出: Array ( [0] => file1.txt [1] => file10.txt [2] => file2.txt [3] => file20.txt [4] => file3.txt )
?>

2. natcasesort()函数

natcasesort()函数使用自然排序算法对数组进行不区分大小写的排序,同时保持键值之间的关联。

<?php
$files = array("File1.txt", "file10.txt", "File2.txt", "file20.txt", "File3.txt");

// 使用不区分大小写的自然排序
natcasesort($files);

// 输出排序后的数组
echo "不区分大小写的自然排序后的文件列表: ";
print_r($files);
// 输出: Array ( [0] => File1.txt [2] => File2.txt [4] => File3.txt [1] => file10.txt [3] => file20.txt )
?>

数组打乱和反向排序

1. shuffle()函数

shuffle()函数用于随机打乱数组中的元素顺序。打乱后,索引数组的索引会被重新分配,而关联数组的键值关联会被保留。

<?php
$numbers = array(1, 2, 3, 4, 5);

// 随机打乱数组
shuffle($numbers);

// 输出打乱后的数组
echo "随机打乱后的数组: ";
print_r($numbers);
// 输出(示例,每次运行结果可能不同): Array ( [0] => 3 [1] => 1 [2] => 5 [3] => 4 [4] => 2 )
?>

2. array_reverse()函数

array_reverse()函数用于反转数组中元素的顺序,同时可以选择是否保留键名。

<?php
$numbers = array(1, 2, 3, 4, 5);

// 反转数组(不保留键名)
$reversed_numbers = array_reverse($numbers);
echo "反转后的数组(不保留键名): ";
print_r($reversed_numbers);
// 输出: Array ( [0] => 5 [1] => 4 [2] => 3 [3] => 2 [4] => 1 )

// 反转数组(保留键名)
$reversed_numbers_with_keys = array_reverse($numbers, true);
echo "反转后的数组(保留键名): ";
print_r($reversed_numbers_with_keys);
// 输出: Array ( [4] => 5 [3] => 4 [2] => 3 [1] => 2 [0] => 1 )
?>

PHP数组排序的最佳实践

  1. 选择合适的排序函数:根据数组类型(索引数组或关联数组)和排序需求(按值排序或按键排序)选择合适的排序函数。
  2. 注意键值关联:使用sort()和rsort()函数会丢失原数组的索引,而使用asort()、arsort()、ksort()和krsort()函数会保持键值之间的关联。
  3. 使用太空船操作符:在PHP 7及以上版本中,使用太空船操作符(<=>)可以简化比较函数的编写。
  4. 使用匿名函数:对于简单的比较逻辑,使用匿名函数可以使代码更简洁。
  5. 考虑自然排序:当需要排序包含数字的字符串时,考虑使用natsort()或natcasesort()函数进行自然排序。
  6. 注意性能问题:对于大型数组,排序操作可能会消耗较多的资源。如果可能,考虑在插入数据时就保持数组的有序性,而不是事后排序。
  7. 使用array_multisort()进行复杂排序:对于需要按多个字段排序的多维数组,可以使用array_multisort()函数。

PHP数组排序综合示例

<?php
// 1. 索引数组排序示例

echo "<h4>1. 索引数组排序示例</h4>";

// 升序排序
$numbers = array(4, 2, 8, 6, 1, 9, 3, 7, 5);
echo "原始数组: " . implode(", ", $numbers) . "<br>";

sort($numbers);
echo "升序排序 (sort): " . implode(", ", $numbers) . "<br>";

// 降序排序
$numbers = array(4, 2, 8, 6, 1, 9, 3, 7, 5);
rsort($numbers);
echo "降序排序 (rsort): " . implode(", ", $numbers) . "<br><br>";

// 2. 关联数组排序示例

echo "<h4>2. 关联数组排序示例</h4>";

$students = array(
    "John" => 85,
    "Mary" => 92,
    "Peter" => 78,
    "David" => 90,
    "Sarah" => 88
);

echo "原始数组: <br>";
foreach ($students as $name => $score) {
    echo "$name: $score<br>";
}

echo "<br>";

// 按值升序排序
$temp = $students;
asort($temp);
echo "按值升序排序 (asort): <br>";
foreach ($temp as $name => $score) {
    echo "$name: $score<br>";
}

echo "<br>";

// 按值降序排序
$temp = $students;
arsort($temp);
echo "按值降序排序 (arsort): <br>";
foreach ($temp as $name => $score) {
    echo "$name: $score<br>";
}

echo "<br>";

// 按键名升序排序
$temp = $students;
ksort($temp);
echo "按键名升序排序 (ksort): <br>";
foreach ($temp as $name => $score) {
    echo "$name: $score<br>";
}

echo "<br>";

// 按键名降序排序
$temp = $students;
krsort($temp);
echo "按键名降序排序 (krsort): <br>";
foreach ($temp as $name => $score) {
    echo "$name: $score<br>";
}

echo "<br><br>";

// 3. 用户自定义排序示例

echo "<h4>3. 用户自定义排序示例</h4>";

// 按字符串长度排序
$words = array("apple", "banana", "cherry", "date", "elderberry");
echo "原始数组: " . implode(", ", $words) . "<br>";

usort($words, function($a, $b) {
    return strlen($a) <=> strlen($b);
});

echo "按字符串长度升序排序 (usort): " . implode(", ", $words) . "<br>";

// 按字符串最后一个字符排序
$words = array("apple", "banana", "cherry", "date", "elderberry");

usort($words, function($a, $b) {
    $last_char_a = substr($a, -1);
    $last_char_b = substr($b, -1);
    return $last_char_a <=> $last_char_b;
});

echo "按最后一个字符排序 (usort): " . implode(", ", $words) . "<br><br>";

// 4. 多维数组排序示例

echo "<h4>4. 多维数组排序示例</h4>";

$employees = array(
    array("id" => 1, "name" => "John Doe", "department" => "HR", "salary" => 50000, "age" => 30),
    array("id" => 2, "name" => "Jane Smith", "department" => "IT", "salary" => 60000, "age" => 28),
    array("id" => 3, "name" => "Mike Johnson", "department" => "Finance", "salary" => 55000, "age" => 35),
    array("id" => 4, "name" => "Lisa Davis", "department" => "Marketing", "salary" => 48000, "age" => 25),
    array("id" => 5, "name" => "Tom Wilson", "department" => "IT", "salary" => 65000, "age" => 32)
);

// 按薪资降序排序
usort($employees, function($a, $b) {
    return $b["salary"] <=> $a["salary"];
});

echo "按薪资降序排序 (usort): <br>";
echo "<table border='1' cellspacing='0' cellpadding='5'>";
echo "<tr><th>ID</th><th>姓名</th><th>部门</th><th>薪资</th><th>年龄</th></tr>";

foreach ($employees as $employee) {
    echo "<tr>";
    echo "<td>" . $employee["id"] . "</td>";
    echo "<td>" . $employee["name"] . "</td>";
    echo "<td>" . $employee["department"] . "</td>";
    echo "<td>$" . $employee["salary"] . "</td>";
    echo "<td>" . $employee["age"] . "</td>";
    echo "</tr>";
}

echo "</table>";

echo "<br>";

// 按部门升序排序,相同部门按年龄降序排序
usort($employees, function($a, $b) {
    if ($a["department"] == $b["department"]) {
        return $b["age"] <=> $a["age"];
    }
    return $a["department"] <=> $b["department"];
});

echo "按部门和年龄排序 (usort): <br>";
echo "<table border='1' cellspacing='0' cellpadding='5'>";
echo "<tr><th>ID</th><th>姓名</th><th>部门</th><th>薪资</th><th>年龄</th></tr>";

foreach ($employees as $employee) {
    echo "<tr>";
    echo "<td>" . $employee["id"] . "</td>";
    echo "<td>" . $employee["name"] . "</td>";
    echo "<td>" . $employee["department"] . "</td>";
    echo "<td>$" . $employee["salary"] . "</td>";
    echo "<td>" . $employee["age"] . "</td>";
    echo "</tr>";
}

echo "</table>";

echo "<br><br>";

// 5. 使用array_multisort()排序多维数组

echo "<h4>5. 使用array_multisort()排序多维数组</h4>";

$products = array(
    array("name" => "iPhone", "price" => 999, "rating" => 4.8),
    array("name" => "Samsung", "price" => 899, "rating" => 4.6),
    array("name" => "Google Pixel", "price" => 799, "rating" => 4.7),
    array("name" => "OnePlus", "price" => 699, "rating" => 4.5),
    array("name" => "Xiaomi", "price" => 599, "rating" => 4.4)
);

// 提取价格和评分列
$prices = array_column($products, "price");
$ratings = array_column($products, "rating");

// 按价格升序和评分降序排序
array_multisort($prices, SORT_ASC, $ratings, SORT_DESC, $products);

echo "使用array_multisort按价格和评分排序: <br>";
echo "<table border='1' cellspacing='0' cellpadding='5'>";
echo "<tr><th>产品名</th><th>价格</th><th>评分</th></tr>";

foreach ($products as $product) {
    echo "<tr>";
    echo "<td>" . $product["name"] . "</td>";
    echo "<td>$" . $product["price"] . "</td>";
    echo "<td>" . $product["rating"] . "</td>";
    echo "</tr>";
}

echo "</table>";

echo "<br><br>";

// 6. 自然排序示例

echo "<h4>6. 自然排序示例</h4>";

$files = array(
    "file1.txt", 
    "file10.txt", 
    "file100.txt", 
    "file2.txt", 
    "file20.txt", 
    "file3.txt"
);

echo "原始数组: " . implode(", ", $files) . "<br>";

// 普通排序
sort($files);
echo "普通排序 (sort): " . implode(", ", $files) . "<br>";

// 自然排序
natsort($files);
echo "自然排序 (natsort): " . implode(", ", $files) . "<br><br>";

// 7. 数组打乱和反向排序

echo "<h4>7. 数组打乱和反向排序</h4>";

// 随机打乱数组
$numbers = range(1, 10);
echo "原始数组: " . implode(", ", $numbers) . "<br>";

shuffle($numbers);
echo "随机打乱后的数组 (shuffle): " . implode(", ", $numbers) . "<br>";

// 数组反转
$reversed = array_reverse($numbers);
echo "反转后的数组 (array_reverse): " . implode(", ", $reversed) . "<br>";

// 保留键名的数组反转
$assoc_array = array("a" => 1, "b" => 2, "c" => 3, "d" => 4, "e" => 5);
echo "<br>原始关联数组: ";
print_r($assoc_array);

echo "<br>反转后的关联数组(保留键名): ";
print_r(array_reverse($assoc_array, true));

echo "<br><br>";

// 8. 实际应用示例

echo "<h4>8. 实际应用示例</h4>";

// 示例1: 按姓氏对联系人列表排序
function sort_contacts_by_last_name($contacts) {
    usort($contacts, function($a, $b) {
        // 提取姓氏(假设名字格式为"名字 姓氏")
        $a_name_parts = explode(" ", $a["name"]);
        $b_name_parts = explode(" ", $b["name"]);
        
        $a_last_name = end($a_name_parts);
        $b_last_name = end($b_name_parts);
        
        return $a_last_name <=> $b_last_name;
    });
    
    return $contacts;
}

// 测试联系人排序
$contacts = array(
    array("name" => "John Smith", "phone" => "123-456-7890"),
    array("name" => "Jane Doe", "phone" => "234-567-8901"),
    array("name" => "Mike Johnson", "phone" => "345-678-9012"),
    array("name" => "Lisa Davis", "phone" => "456-789-0123")
);

$sorted_contacts = sort_contacts_by_last_name($contacts);

echo "<h5>按姓氏排序的联系人列表:</h5>";
echo "<table border='1' cellspacing='0' cellpadding='5'>";
echo "<tr><th>姓名</th><th>电话</th></tr>";

foreach ($sorted_contacts as $contact) {
    echo "<tr>";
    echo "<td>" . $contact["name"] . "</td>";
    echo "<td>" . $contact["phone"] . "</td>";
    echo "</tr>";
}

echo "</table>";

echo "<br>";

// 示例2: 按日期排序日志条目
function sort_logs_by_date($logs) {
    usort($logs, function($a, $b) {
        // 将日期字符串转换为时间戳进行比较
        $a_timestamp = strtotime($a["date"]);
        $b_timestamp = strtotime($b["date"]);
        
        return $b_timestamp <=> $a_timestamp; // 降序排序(最新的在前)
    });
    
    return $logs;
}

// 测试日志排序
$logs = array(
    array("date" => "2023-06-15 10:30:00", "message" => "系统启动成功"),
    array("date" => "2023-06-15 09:15:00", "message" => "用户登录: admin"),
    array("date" => "2023-06-16 14:20:00", "message" => "数据库备份完成"),
    array("date" => "2023-06-16 11:45:00", "message" => "发生错误: 连接超时")
);

$sorted_logs = sort_logs_by_date($logs);

echo "<h5>按日期排序的日志条目(降序):</h5>";
echo "<table border='1' cellspacing='0' cellpadding='5'>";
echo "<tr><th>日期</th><th>消息</th></tr>";

foreach ($sorted_logs as $log) {
    echo "<tr>";
    echo "<td>" . $log["date"] . "</td>";
    echo "<td>" . $log["message"] . "</td>";
    echo "</tr>";
}

echo "</table>";

echo "<br>";

// 示例3: 排序购物车中的商品
function sort_cart_items($cart_items, $sort_by = "price_asc") {
    switch ($sort_by) {
        case "price_asc":
            usort($cart_items, function($a, $b) {
                return $a["price"] <=> $b["price"];
            });
            break;
        case "price_desc":
            usort($cart_items, function($a, $b) {
                return $b["price"] <=> $a["price"];
            });
            break;
        case "name_asc":
            usort($cart_items, function($a, $b) {
                return $a["name"] <=> $b["name"];
            });
            break;
        case "name_desc":
            usort($cart_items, function($a, $b) {
                return $b["name"] <=> $a["name"];
            });
            break;
        case "quantity_asc":
            usort($cart_items, function($a, $b) {
                return $a["quantity"] <=> $b["quantity"];
            });
            break;
        case "quantity_desc":
            usort($cart_items, function($a, $b) {
                return $b["quantity"] <=> $a["quantity"];
            });
            break;
    }
    
    return $cart_items;
}

// 测试购物车排序
$cart_items = array(
    array("name" => "iPhone", "price" => 999, "quantity" => 1),
    array("name" => "无线耳机", "price" => 299, "quantity" => 2),
    array("name" => "手机壳", "price" => 29, "quantity" => 3),
    array("name" => "充电器", "price" => 49, "quantity" => 1)
);

$sorted_cart = sort_cart_items($cart_items, "price_desc");

echo "<h5>按价格降序排序的购物车商品:</h5>";
echo "<table border='1' cellspacing='0' cellpadding='5'>";
echo "<tr><th>商品名</th><th>价格</th><th>数量</th></tr>";

foreach ($sorted_cart as $item) {
    echo "<tr>";
    echo "<td>" . $item["name"] . "</td>";
    echo "<td>$" . $item["price"] . "</td>";
    echo "<td>" . $item["quantity"] . "</td>";
    echo "</tr>";
}

echo "</table>";
?>