PHP实现按字数区间自动计价功能的代码调试求助
PHP自动计价功能调试修复
原代码核心问题
- 条件判断结构不严谨:第二个区间用独立
if而非elseif,虽当前区间无重叠,但逻辑连贯性差,易引发后续维护问题。 - 计价逻辑违反需求:原代码用区间总价格除以区间字数得到单价,再乘以输入字数,会导致跨区间后总价低于低区间最高总价。比如按你给的例子,50字对应50USD、500字对应150USD,原代码计算51字时,单价为150/500=0.3USD,总价51*0.3=15.3USD,远低于50USD,完全不符合“51字价格不得低于50USD”的要求。
- 冗余代码:最后两个区间(>50000和5001-50000)逻辑重复,可合并。
- 无边界异常处理:未处理字数为0的情况,会导致除法报错或总价计算异常。
修复后的代码实现
以下代码实现阶梯计价逻辑,保证高区间价格不低于低区间最高总价,同时支持自定义各区间的字数阈值和对应总价:
// 假设从表单或配置中获取的区间参数(可替换为实际存储的配置值) $price_ranges = [ ['min' => 1, 'max' => 50, 'total_price' => 50], // 1-50字:总价50USD ['min' => 51, 'max' => 500, 'total_price' => 150], // 51-500字:总价150USD(保证51字≥50USD) ['min' => 501, 'max' => 5000, 'total_price' => 400], ['min' => 5001, 'max' => 50000, 'total_price' => 3000], ['min' => 50001, 'max' => PHP_INT_MAX, 'total_price' => 25000] ]; $words = (int)$_POST['words']; // 输入的字数,转为整数避免非数字问题 $total_price = 0; if ($words <= 0) { $total_price = 0; // 字数为0时总价0,可根据需求调整 } else { foreach ($price_ranges as $range) { if ($words >= $range['min'] && $words <= $range['max']) { // 获取前一个区间的最高总价 $prev_max_price = 0; $prev_range_index = array_search($range, $price_ranges) - 1; if ($prev_range_index >= 0) { $prev_max_price = $price_ranges[$prev_range_index]['total_price']; } // 计算当前区间的单价:(当前区间总价 - 前区间总价)/(当前区间最大字数 - 前区间最大字数) $prev_max_words = $prev_range_index >= 0 ? $price_ranges[$prev_range_index]['max'] : 0; $per_word = ($range['total_price'] - $prev_max_price) / ($range['max'] - $prev_max_words); // 计算总价:前区间总价 + (输入字数 - 前区间最大字数)*单价 $total_price = $prev_max_price + ($words - $prev_max_words) * $per_word; // 确保总价不低于前区间最高总价(避免浮点计算精度问题) $total_price = max($total_price, $prev_max_price); break; } } } // 保留两位小数,符合货币格式 $total_price = number_format($total_price, 2); echo "总价:{$total_price} USD";
逻辑说明
- 采用阶梯递增计价:每个区间的总价基于前一个区间的最高总价递增,确保高区间的最低价格(如51字)不低于低区间的最高价格(50字的50USD)。
- 动态计算单价:根据区间的总价差和字数差计算当前区间的单价,保证区间终点(如500字)刚好达到设定的总价。
- 异常处理:处理字数为0的情况,避免计算错误;用
max()保证总价不低于前区间最高值,解决浮点计算精度问题。 - 可扩展性:通过
$price_ranges数组可灵活添加、修改区间,无需修改判断逻辑。
简化版(固定区间单价,保证总价不低于低区间)
如果不需要动态计算单价,可直接为每个区间设置单价,同时强制总价不低于前区间的最高总价:
$words = (int)$_POST['words']; $total_price = 0; if ($words <= 0) { $total_price = 0; } elseif ($words <= 50) { $total_price = $words * 1; // 1USD/字,50字刚好50USD } elseif ($words <= 500) { // 前50字50USD,超出部分按(150-50)/(500-50)=0.222USD/字,500字刚好150USD $total_price = 50 + ($words - 50) * (100/450); $total_price = max($total_price, 50); // 确保不低于50USD } elseif ($words <= 5000) { $total_price = 150 + ($words - 500) * (250/4500); // 示例单价,可调整 $total_price = max($total_price, 150); } elseif ($words <= 50000) { $total_price = 400 + ($words - 5000) * (2600/45000); $total_price = max($total_price, 400); } else { $total_price = 3000 + ($words - 50000) * (22000/PHP_INT_MAX); $total_price = max($total_price, 3000); } $total_price = number_format($total_price, 2); echo "总价:{$total_price} USD";
内容的提问来源于stack exchange,提问作者Naveed Ali
相关产品推荐
相关产品推荐

