商品列表需支援「價格高→低」排序。但部分商品處於促銷期,應以 `promote_price` 參與排序,而資料庫 `ORDER BY` 無法直接處理「動態價格」邏輯。
/**
* 二維陣列快速排序
* @param array $rows 資料集 [ ['id'=>1, 'price'=>100], ... ]
* @param string $key 排序欄位名
* @param string $order 'asc' 或 'desc'
* @return array 排序後新陣列,保留原鍵名
*/
function quickSort2D(array $rows, string $key, string $order = 'asc'): array {
if (count($rows) <= 1) return $rows;
// 提取排序鍵值對應表 [原鍵 => 排序值]
$kv = [];
foreach ($rows as $k => $v) {
if (!isset($v[$key])) continue; // 忽略缺失欄位
$kv[$k] = $v[$key];
}
// 使用 PHP 內建排序 (C 實現,效能遠超純 PHP 遞迴)
if ($order === 'desc') {
arsort($kv);
} else {
asort($kv);
}
// 按排序後的鍵名重組
$sorted = [];
foreach ($kv as $k => $v) {
$sorted[$k] = $rows[$k];
}
return $sorted;
}
// 1. 取得資料 (已按原價排序)
$goods = $db->query("SELECT id, goods_price, promote_price, promote_start, promote_end FROM goods WHERE cat_id=5 ORDER BY goods_price ASC LIMIT 20");
// 2. 判斷促銷有效性,計算顯示價
$now = time();
foreach ($goods as &$g) {
if ($g['promote_price'] > 0 && $now >= $g['promote_start'] && $now <= $g['promote_end']) {
$g['display_price'] = $g['promote_price'];
$g['is_promote'] = true;
} else {
$g['display_price'] = $g['goods_price'];
$g['is_promote'] = false;
}
}
unset($g); // 解除引用
// 3. 以 display_price 重新排序
$sorted = quickSort2D($goods, 'display_price', 'asc');
// 4. 輸出模板
foreach ($sorted as $g) {
echo $g['is_promote'] ? "🔥 {$g['display_price']}" : $g['display_price'];
}
若單頁超過 1000 筆,建議: