💡 今日の3行まとめ
- 配列の合計値は
foreachで足し算せず、array_sum()の1行で求める - 要素が0件(空配列)のときに
count()で割るとDivisionByZeroErrorで停止するため事前判定する - 表示時は
number_format($avg, 1)を使い、4ではなく4.0のように小数点桁数を揃える
1. 今日のお題とゴール
商品に寄せられた星評価(1〜5点)の配列から、レビュー件数と平均点を計算して画面用の文字列に整形する処理を作ります。
foreachループを使わず、array_sum()とcount()で平均点を求める- レビューが
0件(空配列[])のときはエラーを出さず評価なし(0件)と返す - 平均点は小数点第2位を四捨五入し、
4.0のように必ず小数点第1位まで表示する
// 期待する出力結果
イヤホン: ★3.8(4件)
マウス: ★4.0(2件)
新作キーボード: 評価なし(0件)
2. ❌ やりがちなNGコード vs ⭕ コピペで動く正解コード
❌ やりがちなNGコードBefore
<?php
$scores = []; // レビューがまだ0件の商品
// ❌ 1. foreachで毎回ループして合計を計算している
$total = 0;
foreach ($scores as $s) {
$total += $s;
}
// ❌ 2. 0件のときに「0 ÷ 0」となり Fatal error (DivisionByZeroError) で停止!
$average = round($total / count($scores), 1);
PHP 8以降では 0 で割り算を行うと DivisionByZeroError が発生し、プログラムが即座に停止します。また、round(4.0, 1) は数値の 4 になるため、4.0 のように末尾の .0 が表示されません。
⭕ コピペで動く正解コード(PHP 8.3+)After
<?php
declare(strict_types=1);
function formatReviewSummary(array $scores): string
{
$count = count($scores);
// 0件のときは割り算をせずに早期リターン(ゼロ除算の防止)
if ($count === 0) {
return '評価なし(0件)';
}
// array_sum() で配列の数値を一括合計して平均を算出
$average = array_sum($scores) / $count;
// 小数点第1位まで固定フォーマット(4 -> '4.0'、3.75 -> '3.8')
$formattedAvg = number_format($average, 1);
return "★{$formattedAvg}({$count}件)";
}
$products = [
'イヤホン' => [5, 4, 3, 3], // 平均 3.75 -> 3.8
'マウス' => [5, 3], // 平均 4 -> 4.0
'新作キーボード' => [], // 0件
];
foreach ($products as $name => $scores) {
echo "{$name}: " . formatReviewSummary($scores) . "\n";
}
3. ここだけ押さえる!3つのポイント
1合計計算は
array_sum() で1行にするarray_sum() に数値の配列を渡すだけで、すべての要素を足し合わせた合計値が返ります。集計用の変数 $total = 0 や foreach ループを書く必要がなくなり、計算ミスも防げます。
2割り算の前に必ず
$count === 0 をチェックする新商品など、配列が空(0件)になるケースは実務でよくあります。割り算の前に件数が 0 なら早期リターン(return)して処理を抜けましょう。
3表示用の小数点揃えには
round() より number_format()round(4.0, 1) は数値の 4 を返すため、画面に出すと .0 が消えてしまいます。number_format($average, 1) なら四捨五入しつつ文字列の '4.0' に整形してくれるため、表示桁が綺麗に揃います。
4. 1分ミニチャレンジ
🚀 手を動かしてみよう
正解コードの number_format($average, 1) を number_format($average, 2) に変えて実行してみましょう。イヤホンの平均点(3.75)やマウスの平均点(4)の表示はどう変わるでしょうか?(ヒント:第2引数で指定した桁数まで、末尾の 0 が自動で補われます)