【PHP】レッスン2-09:例外処理を理解しよう

記事内に商品プロモーションを含む場合があります

この記事で学べる知識:例外処理

この記事の練習問題を解くために必要な知識:
比較演算子と論理演算子if文による分岐処理条件演算子switch文による分岐処理for文による繰り返し処理while文による繰り返し処理繰り返しの制御エラーメッセージ例外処理

<<前のページ PHP記事一覧 次のページ>>

PHPの「例外処理」とは

この章ではPHPにおける「例外処理」の意味や使い方を学習します。用語の解説が不要な方はここをクリックして練習問題へ飛びましょう。




プログラムを実行していると、予期しないエラーが発生することがあります。

例えば存在しないファイルを開こうとしたり、ゼロで割り算を試みたりする場合です。

このようなエラーを適切に処理しないと、プログラムが突然終了してしまい、ユーザー体験に悪影響を及ぼします。

例外処理とは、エラー(例外)を検知して、プログラムの実行を安全に継続する仕組みです。

PHPではtrycatch、およびfinallyを使用して例外処理を行います。

例外処理の基本構文

PHPの例外処理は、以下の構文で記述します。

try {
    // 例外が発生する可能性のあるコード
} catch (例外クラス $例外オブジェクト) {
    // 例外が発生したときの処理
} finally {
    // 例外の有無に関わらず必ず実行される処理
}
  • tryブロック: エラーが発生する可能性のあるコードを記述します。
  • catchブロック: tryブロックで例外が発生した際の処理を記述します。ここで例外をキャッチし、必要な対策を行います。
  • finallyブロック: 必要に応じて使用します。例外が発生したかどうかに関係なく、必ず実行される処理を記述します。

例外オブジェクト(通常はExceptionクラスを使用)には、エラーメッセージやエラーコードなどの情報が格納されます。

例外処理の使用例

以下は、例外処理の具体的な例です。

<?php
function divide($a, $b) {
    if ($b === 0) {
        throw new Exception("ゼロによる割り算は許可されていません。");
    }
    return $a / $b;
}

try {
    echo divide(10, 0); // ここで例外が発生します
} catch (Exception $e) {
    echo "エラー: " . $e->getMessage() . PHP_EOL; // 例外メッセージを表示
} finally {
    echo "例外処理の終了。" . PHP_EOL; // 必ず実行される処理
}
  • 関数divideでゼロによる割り算が試みられた場合、throwで例外を発生させます。
  • tryブロック内で例外がキャッチされ、catchブロックに処理が移ります。
  • 最後にfinallyブロックの内容が実行されます。

例外処理を使うメリットと注意点

例外処理を行う際のメリットと注意点を紹介します。

例外処理のメリット

  1. エラーを局所化: 問題が発生した箇所にフォーカスして適切に対処できます。
  2. コードの読みやすさ向上: エラーチェックのコードを分離することで、主要なロジックが分かりやすくなります。
  3. プログラムの安定性向上: 想定外のエラーが発生しても、プログラムの異常終了を防ぐことができます。

例外処理の注意点

  1. 過剰な例外使用の回避: 通常の条件分岐で解決できる問題には例外処理を使用しないほうが良いです。
  2. catchブロックの適切な設計: 必要な処理だけを実装し、無意味な例外キャッチは避けるべきです。

まとめ

例外処理はエラー発生時にプログラムの挙動をコントロールする強力な仕組みです。

trycatchfinallyを理解し、適切に使用することで、より堅牢で安定したコードを作成できます。

初心者の方はまずは基本構文と簡単な例を練習し、例外処理を使いこなせるようにしましょう。

例外処理の練習問題:安全な割り算プログラムを作成しよう

ユーザーから入力された2つの数値を使って割り算を行うプログラムを作成しましょう。

ただし、ゼロで割るとエラーが発生します。

このエラーを例外処理を使って安全に処理し、プログラムを終了させずにユーザーにエラーメッセージを表示してください。

割り算が成功した場合は結果を出力し、プログラムの最後には必ず終了メッセージを表示するようにしましょう。

この問題の要件

以下の要件に従ってコードを完成させてください。

  • 標準入力を使用して、2つの整数を取得すること。
  • ゼロで割ろうとした場合、例外を発生させること。
  • tryブロック内に割り算の処理を記述すること。
  • catchブロックで例外をキャッチし、ユーザーにエラーメッセージを表示すること。
  • finallyブロックでプログラム終了メッセージを表示すること。
  • 割り算が成功した場合、計算結果を画面に出力すること。

ただし、以下のような実行結果となるコードを書くこと。

*****↓↓正解コードの実行結果の例↓↓*****

割られる数を入力してください: 
10
割る数を入力してください: 
0
エラー: ゼロで割ることはできません!
プログラムを終了します。

この問題を解くヒント

1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。

ヒント1【コードの構成を見る】

正解のコードは上から順に以下のような構成となっています。
(※下記の□はコード内のインデントを表しています)

1:PHPスクリプトの開始を宣言
2:「割られる数を入力してください: 」と出力
3:標準入力から値を取得し、整数型にキャストして変数$numeratorに代入
4:「割る数を入力してください: 」と出力
5:標準入力から値を取得し、整数型にキャストして変数$denominatorに代入
6:tryブロックを開始
  □ if文で$denominatorが0であるか判定
  □ □ 真の場合、Exceptionオブジェクトをスロー
  □ $numeratorを$denominatorで割り、結果を変数$resultに代入
  □ 「計算結果: 」と$resultを出力
7:catchブロックを開始
  □ Exceptionオブジェクトのメッセージを取得し、「エラー: 」として出力
8:finallyブロックを開始
  □ 「プログラムを終了します。」と出力

ヒント2【穴埋め問題にする】

以下のコードをコピーし、コメントに従ってコードを完成させて下さい。

<?php

// 標準入力から2つの数値を取得します
echo "割られる数を入力してください: " . PHP_EOL;
$numerator = (int)fgets(STDIN); // 入力を整数にキャスト
echo "割る数を入力してください: " . PHP_EOL;
$denominator = (int)fgets(STDIN); // 入力を整数にキャスト

try {
    /*【穴埋め問題1】
    ここで$denominatorが0かどうかを判定し、例外をスローするコードを書いてください。
    */

    // 割り算の結果を計算
    $result = $numerator / $denominator;

    // 結果を出力
    echo "計算結果: " . $result . PHP_EOL;

} catch (Exception $e) {
    /*【穴埋め問題2】
    ここで例外オブジェクトのメッセージを取得し、「エラー: 」として出力するコードを書いてください。
    */
} finally {
    /*【穴埋め問題3】
    ここで必ず実行される処理として、「プログラムを終了します。」と出力するコードを書いてください。
    */
}

以上がこの問題の穴埋めコードです。

このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。



練習問題の解答と解説

この問題の一つの正解例とそのコードの解説を以下に示します。

正解コードの例

例えば以下のようなプログラムが考えられます。

 

<?php

// 標準入力から2つの数値を取得します
echo "割られる数を入力してください: " . PHP_EOL;
$numerator = (int)fgets(STDIN); // 入力を整数にキャスト
echo "割る数を入力してください: " . PHP_EOL;
$denominator = (int)fgets(STDIN); // 入力を整数にキャスト

try {
    // 例外が発生する可能性があるコード
    if ($denominator === 0) {
        // ゼロで割る場合は例外をスローします
        throw new Exception("ゼロで割ることはできません!");
    }

    // 割り算の結果を計算
    $result = $numerator / $denominator;

    // 結果を出力
    echo "計算結果: " . $result . PHP_EOL;

} catch (Exception $e) {
    // 例外が発生した場合の処理
    echo "エラー: " . $e->getMessage() . PHP_EOL; // エラーメッセージを表示
} finally {
    // 必ず実行される処理
    echo "プログラムを終了します。" . PHP_EOL;
}

正解コードの解説

このコードは、例外処理を使って割り算中のエラーを安全に処理する方法を学ぶものです。

コードをブロックごとに分解して解説します。

PHPタグと標準入力の処理

<?php
echo "割られる数を入力してください: " . PHP_EOL;
$numerator = (int)fgets(STDIN);
echo "割る数を入力してください: " . PHP_EOL;
$denominator = (int)fgets(STDIN);
  • PHPタグ (<?php): PHPコードの開始を示します。これがないとPHPスクリプトとして認識されません。
  • fgets(STDIN): 標準入力からユーザーの入力を取得します。このコードでは割られる数と割る数の両方を入力します。
  • (int): ユーザーが入力した値を整数型に変換します。文字列のままでは計算できないため、キャストが必要です。
  • PHP_EOL: 改行コードを表します。環境に依存せずに改行を出力できます。

例外処理の構造

try {
    if ($denominator === 0) {
        throw new Exception("ゼロで割ることはできません!");
    }
    $result = $numerator / $denominator;
    echo "計算結果: " . $result . PHP_EOL;
} catch (Exception $e) {
    echo "エラー: " . $e->getMessage() . PHP_EOL;
} finally {
    echo "プログラムを終了します。" . PHP_EOL;
}
tryブロック
  • try: エラーが発生する可能性があるコードを囲みます。今回は割り算の計算部分を含みます。
  • if ($denominator === 0): 入力された割る数が0の場合をチェックします。ゼロ割は計算エラーの原因となるため、事前に対処します。
  • throw new Exception("メッセージ"): 特定の条件(ここでは割る数がゼロ)で例外を発生させます。
    例外オブジェクトにエラーメッセージを持たせることができます。
  • $numerator / $denominator: 割り算の計算を行います。
catchブロック
  • catch (Exception $e): tryブロックで発生した例外を受け取ります。$eは例外オブジェクトで、詳細なエラー情報を保持します。
  • $e->getMessage(): 発生した例外に含まれるメッセージ(今回の場合は「ゼロで割ることはできません!」)を取得します。
finallyブロック
  • finally: tryブロックで例外が発生してもしなくても、必ず実行される処理を書きます。
    このコードではプログラム終了のメッセージを表示します。

まとめ

このコードでは、例外処理の基本的な構造(trycatchfinally)を学ぶことができます。

エラーが発生してもプログラムが安全に動作を続ける仕組みを提供する例外処理は、堅牢なアプリケーションを作る上で不可欠です。

初心者の方はこのコードを基にいろいろな条件で例外処理を試し、理解を深めていきましょう。

<<前のページ PHP記事一覧 次のページ>>

この記事への質問・コメント

この記事を作成するにあたりAIを活用しています。

問題ないことは確認していますが、もし間違いや表現の違和感などありましたら、ご指摘頂けると大変助かります。






    PHPのテキスト&問題集トップへ戻る
    トップページへ戻る