PHPの剰余演算子について

採用はこちら

PHPの剰余演算子とは、割り算をしたときの「余り」を求めるための演算子です。

PHPでは、剰余演算子として % を使用します。

たとえば、次のコードを見てみましょう。

echo 10 % 3;

出力結果は以下のようになります。

1

10を3で割ると、商は3で余りは1です。

そのため、10 % 3 の結果は 1 になります。

剰余演算子は、単に余りを求めるだけでなく、偶数・奇数の判定、倍数の判定、一定回数ごとの処理、表示パターンの切り替えなど、さまざまな場面で使われます。

目次

剰余演算子の基本的な書き方

PHPの剰余演算子は、次のように書きます。

$a % $b

この場合、$a$b で割ったときの余りが返されます。

たとえば、次のように使います。

$num = 17;

echo $num % 5;

出力結果は以下です。

2

17を5で割ると、5 × 3 = 15で、余りは2です。

したがって、17 % 5 の結果は 2 になります。

剰余演算子の基本例

剰余演算子の基本的な計算例を見てみましょう。

echo 8 % 2;  // 0
echo 9 % 2;  // 1
echo 10 % 4; // 2
echo 15 % 6; // 3

それぞれの意味は次の通りです。

8 % 2 は、8を2で割った余りを求めます。8は2で割り切れるため、結果は 0 です。

9 % 2 は、9を2で割った余りを求めます。9を2で割ると余りは1なので、結果は 1 です。

10 % 4 は、10を4で割った余りを求めます。10を4で割ると余りは2なので、結果は 2 です。

15 % 6 は、15を6で割った余りを求めます。15を6で割ると余りは3なので、結果は 3 です。

このように、剰余演算子を使うと「割り切れるかどうか」「余りはいくつか」を簡単に確認できます。

PHPの剰余演算子は整数の剰余を求める演算子

PHPの % は、基本的に整数の剰余を求める演算子です。

そのため、% の計算では、左辺と右辺の値が整数として扱われます。

小数を使った場合は、計算前に整数へ変換されます。

たとえば、次のコードを見てみましょう。

echo 10.5 % 3;

この場合、10.5 は整数の 10 として扱われます。

そのため、実際には次のような計算になります。

echo 10 % 3;

出力結果は以下です。

1

また、右辺に小数を指定した場合も整数へ変換されます。

echo 10 % 2.5;

この場合、2.5 は整数の 2 として扱われるため、実際には次のような計算になります。

echo 10 % 2;

結果は 0 です。

このように、PHPの % は小数の余りを正確に求めるための演算子ではありません。

小数を含む剰余を求めたい場合は、後述する fmod() 関数を使います。

偶数・奇数の判定に使う

剰余演算子は、偶数・奇数を判定するときによく使われます。

偶数は2で割り切れる数です。つまり、2で割った余りが 0 になる数です。

$num = 10;

if ($num % 2 === 0) {
    echo "偶数です";
} else {
    echo "奇数です";
}

出力結果は以下です。

偶数です

10 % 2 の結果は 0 です。

そのため、10は偶数と判定されます。

奇数を判定する場合は、2で割った余りが 0 ではないかどうかを確認すると安全です。

$num = 7;

if ($num % 2 !== 0) {
    echo "奇数です";
} else {
    echo "偶数です";
}

出力結果は以下です。

奇数です

正の整数だけを扱う場合は、次のように書いても奇数を判定できます。

if ($num % 2 === 1) {
    echo "奇数です";
}

ただし、負の数を扱う可能性がある場合は、=== 1 ではなく !== 0 を使う方が安全です。

たとえば、PHPでは次のような結果になります。

echo -7 % 2;

出力結果は以下です。

-1

-7 % 2 の結果は 1 ではなく -1 です。

そのため、負の数も含めて奇数を判定したい場合は、次のように書くのが適しています。

if ($num % 2 !== 0) {
    echo "奇数です";
}

倍数の判定に使う

剰余演算子は、ある数が特定の数の倍数かどうかを判定するときにも便利です。

たとえば、3の倍数かどうかを判定する場合は、次のように書けます。

$num = 12;

if ($num % 3 === 0) {
    echo "3の倍数です";
} else {
    echo "3の倍数ではありません";
}

出力結果は以下です。

3の倍数です

12 % 3 の結果は 0 です。

つまり、12は3で割り切れるため、3の倍数と判断できます。

5の倍数を判定する場合も同じです。

$num = 25;

if ($num % 5 === 0) {
    echo "5の倍数です";
}

このように、剰余演算子は「割り切れるかどうか」を判定する処理でよく使われます。

FizzBuzzで使う例

剰余演算子の代表的な使用例として、FizzBuzzがあります。

FizzBuzzとは、1から順番に数を確認し、3の倍数なら Fizz、5の倍数なら Buzz、3と5の両方の倍数なら FizzBuzz と表示する処理です。

for ($i = 1; $i <= 15; $i++) {
    if ($i % 15 === 0) {
        echo "FizzBuzz\n";
    } elseif ($i % 3 === 0) {
        echo "Fizz\n";
    } elseif ($i % 5 === 0) {
        echo "Buzz\n";
    } else {
        echo $i . "\n";
    }
}

このコードでは、剰余演算子を使って、それぞれの数が3や5で割り切れるかどうかを判定しています。

$i % 3 === 0 は、$i が3の倍数であることを意味します。

$i % 5 === 0 は、$i が5の倍数であることを意味します。

$i % 15 === 0 は、$i が15の倍数であることを意味します。

15は3と5の最小公倍数なので、3の倍数でもあり、5の倍数でもある数を判定できます。

このように、剰余演算子は条件分岐と組み合わせて使われることが多いです。

一定回数ごとの処理に使う

剰余演算子は、繰り返し処理の中で「一定回数ごとに処理を実行したい」ときにも役立ちます。

たとえば、3回に1回だけメッセージを表示したい場合は、次のように書けます。

for ($i = 1; $i <= 10; $i++) {
    echo $i . "\n";

    if ($i % 3 === 0) {
        echo "3回ごとの処理です\n";
    }
}

このコードでは、$i が3、6、9のときに「3回ごとの処理です」と表示されます。

Web制作では、次のような場面で剰余演算子が使われることがあります。

3件ごとに区切り線を入れる
4件ごとに広告を挿入する
偶数番目と奇数番目でCSSクラスを変える
一定件数ごとにHTML構造を切り替える

たとえば、記事一覧で3件ごとに区切りを入れたい場合は、次のように書けます。

$posts = ['記事1', '記事2', '記事3', '記事4', '記事5', '記事6'];

foreach ($posts as $index => $post) {
    echo '<div class="post">' . $post . '</div>';

    if (($index + 1) % 3 === 0) {
        echo '<hr>';
    }
}

ここでは、$index + 1 を使っている点が重要です。

PHPの配列インデックスは通常 0 から始まります。

つまり、1件目の $index0、2件目は 1、3件目は 2 です。

表示上の件数として「3件目ごと」と判定したい場合は、$index ではなく $index + 1 を使うとわかりやすくなります。

偶数行・奇数行で表示を変える

剰余演算子は、HTMLの出力で偶数行・奇数行の表示を変えたい場合にも使えます。

たとえば、リストの行ごとにCSSクラスを変える場合は、次のように書けます。

$items = ['りんご', 'バナナ', 'みかん', 'ぶどう'];

foreach ($items as $index => $item) {
    $class = ($index % 2 === 0) ? 'even' : 'odd';

    echo '<p class="' . $class . '">' . $item . '</p>';
}

このコードでは、$index が偶数なら even、奇数なら odd というクラスを付けています。

ただし、$index は0から始まるため、1件目の $index0 です。

そのため、上記のコードでは1件目に even が付きます。

表示上の「1行目」を奇数行として扱いたい場合は、次のように $index + 1 を使います。

$items = ['りんご', 'バナナ', 'みかん', 'ぶどう'];

foreach ($items as $index => $item) {
    $rowNumber = $index + 1;

    $class = ($rowNumber % 2 === 0) ? 'even' : 'odd';

    echo '<p class="' . $class . '">' . $item . '</p>';
}

この書き方であれば、1行目を odd、2行目を even として扱えます。

配列の値を順番に繰り返す

剰余演算子は、配列の値を順番に繰り返し使いたい場合にも便利です。

たとえば、複数のCSSクラスを順番に付けたい場合を考えてみましょう。

$classes = ['type-a', 'type-b', 'type-c'];

for ($i = 0; $i < 10; $i++) {
    $class = $classes[$i % count($classes)];

    echo '<div class="' . $class . '">項目' . $i . '</div>';
}

count($classes)3 です。

そのため、$i % count($classes) の結果は、012 のいずれかになります。

$i = 0 のとき 0 % 3 = 0
$i = 1 のとき 1 % 3 = 1
$i = 2 のとき 2 % 3 = 2
$i = 3 のとき 3 % 3 = 0
$i = 4 のとき 4 % 3 = 1
$i = 5 のとき 5 % 3 = 2

つまり、配列の添字が 0 → 1 → 2 → 0 → 1 → 2 のように繰り返されます。

これにより、type-atype-btype-c のクラスを順番に繰り返し付けることができます。

小数の剰余を求める場合はfmod関数を使う

PHPの % は整数の剰余を求める演算子です。

そのため、小数を含む剰余を求めたい場合には適していません。

小数を含む剰余を求めたい場合は、fmod() 関数を使います。

echo fmod(10.5, 3);

出力結果は以下です。

1.5

10.5を3で割ると、3 × 3 = 9で、余りは1.5です。

そのため、fmod(10.5, 3) の結果は 1.5 になります。

% を使った場合と比較すると、違いがわかりやすくなります。

echo 10.5 % 3;     // 1
echo fmod(10.5, 3); // 1.5

10.5 % 3 では、10.5 が整数の 10 に変換されてから計算されます。

そのため、結果は 1 です。

一方、fmod(10.5, 3) は浮動小数点数として剰余を求めるため、結果は 1.5 になります。

小数を含む計算では、%fmod() の違いを理解して使い分けることが重要です。

右辺が0になるとエラーになる

剰余演算子を使うときは、右辺の値が 0 にならないように注意が必要です。

次のようなコードは実行できません。

echo 10 % 0;

PHPで右辺に 0 を指定して剰余演算を行うと、DivisionByZeroError が発生します。

そのため、右辺の値が変数の場合は、事前に0ではないかを確認してから計算する必要があります。

$a = 10;
$b = 0;

if ($b !== 0) {
    echo $a % $b;
} else {
    echo "0では割れません";
}

また、小数を使う場合にも注意が必要です。

echo 10 % 0.5;

PHPの % では、右辺の 0.5 が整数の 0 に変換されます。

その結果、10 % 0 と同じ扱いになり、エラーが発生します。

このような理由から、小数を含む剰余計算では % ではなく fmod() を使う方が適切です。

負の数を扱う場合は結果の符号に注意する

PHPで負の数を使って剰余演算を行う場合は、結果の符号に注意が必要です。

PHPの剰余演算では、結果の符号は左辺の値、つまり割られる数の符号に従います。

たとえば、次のコードを見てみましょう。

echo -10 % 3;

出力結果は以下です。

-1

-103 で割った場合、PHPでは剰余の結果が -1 になります。

一方、右辺が負の数でも、左辺が正の数であれば結果は正になります。

echo 10 % -3;

出力結果は以下です。

1

さらに、次のように確認すると、結果の符号が左辺に従うことがわかります。

var_dump(5 % 3);    // int(2)
var_dump(5 % -3);   // int(2)
var_dump(-5 % 3);   // int(-2)
var_dump(-5 % -3);  // int(-2)

剰余という言葉から「結果は常に0以上になる」と考えてしまうことがありますが、PHPではそうとは限りません。

特に、曜日計算、配列の循環、ページ番号の補正などで負の値を扱う場合は注意が必要です。

常に正の剰余を得たい場合

負の数を扱う処理では、剰余の結果を常に 0 以上にしたい場合があります。

たとえば、7つの要素を循環させる処理で -1 を扱う場合、PHPの通常の剰余では次のようになります。

echo -1 % 7;

出力結果は以下です。

-1

しかし、循環するインデックスとして考えるなら、-16 として扱いたい場合があります。

そのような場合は、次のような関数を用意すると便利です。

function positiveMod(int $a, int $b): int
{
    if ($b <= 0) {
        throw new InvalidArgumentException('$b must be a positive integer.');
    }

    return (($a % $b) + $b) % $b;
}

echo positiveMod(-1, 7);

出力結果は以下です。

6

この関数では、通常の剰余計算で負の値が出た場合でも、最終的に 0 以上の値に補正できます。

ただし、この関数は $b が正の整数であることを前提にしています。

そのため、$b が0以下の場合は例外を投げるようにしています。

剰余代入演算子も使える

PHPでは、剰余演算子と代入演算子を組み合わせた書き方もできます。

$a %= $b;

これは、次のコードと同じ意味です。

$a = $a % $b;

たとえば、次のように使えます。

$num = 17;

$num %= 5;

echo $num;

出力結果は以下です。

2

最初に $num には 17 が入っています。

その後、$num %= 5; によって、$num = $num % 5; と同じ処理が行われます。

つまり、17 % 5 の結果である 2$num に代入されます。

この書き方は、変数の値を剰余の結果で更新したいときに使えます。

比較するときは厳密比較を使う

剰余演算子は、条件分岐と組み合わせて使うことが多いです。

特に多いのが、余りが 0 かどうかを判定する書き方です。

if ($num % 2 === 0) {
    echo "偶数です";
}

ここで使っている === は、厳密比較演算子です。

PHPには ===== があります。

== は値が等しいかを比較し、必要に応じて型変換が行われます。一方、=== は値だけでなく型も含めて比較します。

% の結果は整数になるため、次のように書いても多くの場合は動作します。

if ($num % 2 == 0) {
    echo "偶数です";
}

しかし、PHPでは型変換による意図しない挙動を避けるため、条件式では次のように === を使う方が安全です。

if ($num % 2 === 0) {
    echo "偶数です";
}

特に、フォーム入力や外部データを扱うコードでは、型を意識した比較をすることが大切です。

数値文字列を使う場合の注意点

PHPでは、数値として解釈できる文字列を剰余演算に使うこともできます。

echo "10" % "3";

この場合、文字列の "10""3" は数値として扱われ、結果は次のようになります。

1

ただし、文字列のまま計算に使うと、コードの意図がわかりにくくなることがあります。

特に、フォームから送信された値や外部APIから取得した値は、文字列として渡されることが多いです。

そのため、必要に応じて整数に変換し、バリデーションを行ってから剰余演算を使う方が安全です。

$a = (int) $_POST['a'];
$b = (int) $_POST['b'];

if ($b !== 0) {
    echo $a % $b;
} else {
    echo "0では割れません";
}

実務では、単に (int) で変換するだけでなく、入力値が本当に数値として妥当かどうかも確認することが重要です。

剰余演算子の優先順位

PHPの剰余演算子 % は、掛け算 * や割り算 / と同じグループの演算子です。

足し算 + や引き算 - よりも優先して計算されます。

たとえば、次のコードを見てみましょう。

$result = 10 + 6 % 4;

echo $result;

出力結果は以下です。

12

これは、先に 6 % 4 が計算されるためです。

6 % 4 // 2
10 + 2 // 12

一方、次のようにかっこを使うと、計算順序が変わります。

$result = (10 + 6) % 4;

echo $result;

出力結果は以下です。

0

この場合は、先に 10 + 6 が計算されます。

10 + 6 // 16
16 % 4 // 0

複雑な式を書く場合は、演算子の優先順位に頼りすぎず、かっこを使って意図を明確にすると読みやすくなります。

剰余演算子を使うときの注意点

PHPの剰余演算子を使うときは、いくつか注意点があります。

右辺を0にしない

剰余演算では、右辺が 0 になると計算できません。

echo 10 % 0;

このようなコードでは、DivisionByZeroError が発生します。

変数を使う場合は、事前に0ではないことを確認しましょう。

if ($b !== 0) {
    echo $a % $b;
}

小数にはfmod関数を使う

% は整数の剰余を求める演算子です。

小数を含む剰余を求めたい場合は、fmod() を使います。

echo fmod(10.5, 3);

負の数では結果の符号に注意する

PHPでは、剰余の結果の符号は左辺に従います。

echo -10 % 3; // -1

負の数を扱う場合は、結果が必ず0以上になるとは限らない点に注意しましょう。

奇数判定では !== 0 を使うと安全

正の整数だけであれば、奇数判定に === 1 を使うこともできます。

if ($num % 2 === 1) {
    echo "奇数です";
}

しかし、負の数を扱う可能性がある場合は、次のように書く方が安全です。

if ($num % 2 !== 0) {
    echo "奇数です";
}

比較には厳密比較を使う

剰余の結果を比較するときは、=== を使うと型変換による誤判定を避けやすくなります。

if ($num % 2 === 0) {
    echo "偶数です";
}

PHPの剰余演算子の実用例

PHPの剰余演算子は、次のような場面でよく使われます。

偶数・奇数を判定する

$num = 8;

if ($num % 2 === 0) {
    echo "偶数";
} else {
    echo "奇数";
}

倍数かどうかを判定する

$num = 15;

if ($num % 5 === 0) {
    echo "5の倍数";
}

一定回数ごとに処理する

for ($i = 1; $i <= 30; $i++) {
    if ($i % 10 === 0) {
        echo "10回ごとの処理\n";
    }
}

CSSクラスを切り替える

$class = ($index % 2 === 0) ? 'even' : 'odd';

配列の値を循環させる

$colors = ['red', 'blue', 'green'];

for ($i = 0; $i < 10; $i++) {
    echo $colors[$i % count($colors)] . "\n";
}

このコードでは、redbluegreen が順番に繰り返し表示されます。

まとめ

PHPの剰余演算子は、割り算をしたときの余りを求めるための演算子です。

記号は % を使います。

echo 10 % 3; // 1

剰余演算子は、次のような処理でよく使われます。

偶数・奇数の判定
倍数の判定
一定回数ごとの処理
偶数行・奇数行の表示切り替え
配列の値のローテーション
FizzBuzzのような条件分岐

特に、偶数判定では次のような書き方がよく使われます。

if ($num % 2 === 0) {
    echo "偶数です";
}

また、奇数判定では、負の数も考慮するなら次のように書くと安全です。

if ($num % 2 !== 0) {
    echo "奇数です";
}

ただし、PHPの % は整数の剰余を求める演算子です。

小数を含む剰余を求めたい場合は、fmod() 関数を使います。

echo fmod(10.5, 3); // 1.5

さらに、右辺が 0 の場合は DivisionByZeroError が発生します。

変数を使って剰余演算を行う場合は、事前に0ではないかを確認することが重要です。

if ($b !== 0) {
    echo $a % $b;
}

PHPの剰余演算子を理解しておくと、条件分岐や繰り返し処理、HTML出力の制御などをより柔軟に書けるようになります。

以上、PHPの剰余演算子についてでした。

最後までお読みいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次