[模擬問題] PHP8初級 – 例外(CTO古庄道明からの出題)

こんにちは。PHP技術者認定機構 CTOの古庄道明です。
今日もPHP8初級試験の模擬問題と解説を紹介します。
以下を解いて出題のイメージと知識を補っていただけると幸いです。

目次

問題

次の実行結果を得たい場合に、コードの【A】【B】【C】に入るものとして正しい組み合わせはどれか。

[ 実行結果 ]
16 is a multiple of 8, 13 is indivisible by 4

[ コード ]

function calc($a, $b) {
    if ($a % $b !== 0){
        【A】 new Exception($a . ' is indivisible by ' . $b);
    }

    return ($a . ' is a multiple of ' . $b);
}

try {
    print calc(16, 8). ", ";
    print calc(13, 4). ", ";
    print calc(10, 2). ", ";
} 【B】 (Exception $e) {
    print $e->【C】;
}

選択肢

選択肢1
【A】through 【B】catch 【C】getMsg()

選択肢2
【A】through 【B】error 【C】print()

選択肢3
【A】through 【B】error 【C】getError()

選択肢4
【A】throw 【B】error 【C】print()

選択肢5
【A】throw 【B】catch 【C】getMessage()

回答と解説

問題は「例外について」です。
https://www.php.net/manual/ja/control-structures.try-catch.php
に一通り記載があるので、確認をしておくとよいでしょう。

今回の設問はコードを実行順に読んでいくとよいので、ゆっくりコードを解読していきましょう。

まず

function calc($a, $b) {

からの関数の定義は、実際に関数が呼ばれる時に確認をしていきます。

try {

は、例外が投げられる可能性があるコードを囲むものです。

    print calc(16, 8). ", ";

は、関数の calc() を引数 16,8 で呼び出し、その結果と、最後にカンマを出力しようとしています。

関数の calc() が呼ばれましたので、関数の中を見ていきましょう。

    if ($a % $b !== 0){

の行を見ていきましょう。
ここには % と !== の2つの演算子があります。
https://www.php.net/manual/ja/language.operators.precedence.php
の演算子の優先順位を確認すると「%」「!==」の順番のため、先に $a % $b を処理して、その結果を使って !== 0 を演算していきます。

まず $a % $b は「第一引数 $a を 第二引数 $b で割ったあまり」を算出しています。
今回は 16 % 8 なので、これは「2 余り 0」なので、0になります。

次に、0 !== 0 となるため、これは false になるので、ifの中は通りません。
そのため

    return ($a . ' is a multiple of ' . $b);

となるため、calc(16, 8) の戻り値は
16 is a multiple of 8
となります。

改めて元のコードを見ていきましょう。

    print calc(16, 8). ", ";

こちらでしたね。
そのため、これは

    print '16 is a multiple of 8'. ", ";

となるため、出力としては

16 is a multiple of 8,

となります(最後に改行がないので、次の出力はそのままこの行の後ろにつながります)。

次は以下の行です。

    print calc(13, 4). ", ";

同じく calc() を見ていきましょう。
まず $a % $b は「第一引数 $a を 第二引数 $b で割ったあまり」を算出しています。
今回は 13 % 4 なので、これは「3 余り 1」なので、1になります。

次に、1 !== 0 となるため、これは true になるので、ifの中を通ります。

        【A】 new Exception($a . ' is indivisible by ' . $b);

この 【A】 には何が入るでしょうか?
慣れた人であれば new Exception(...) 時点で気づくかもしれません。
そうでない場合は、期待される実行結果を確認してみましょう。

16 is a multiple of 8, 13 is indivisible by 4

このうち、

16 is a multiple of 8,

はすでに出力済みです。そのため、その後に続く

13 is indivisible by 4

が出力される必要があります。
そのために、calc() の return の行にコードが進まなくなる必要があります。

【A】 new Exception()

このように、Exception オブジェクトを作成して「例外を投げる」処理を記述するには、throw キーワードを使います。

try ブロック内で例外が投げられると、最初にマッチする catch ブロックを探します。
そのため

} 【B】 (Exception $e) {

の 【B】 は、 catch になります。
catch ブロックの処理を見てみましょう。

    print $e->【C】;

とあります。
new Exception() で例外を作成するときに渡した文字列が、例外のメッセージになります。このメッセージを取得するメソッドは getMessage() です。
従って、【C】 は getMessage() となります。

また、例外が投げられると calc() の処理だけでなく、呼び出し元の try ブロックの処理も中断されます。
そのため、print calc(13, 4). ", "; の出力処理と、続く calc(10, 2) は、実行されません。

少しかみ砕きますと。

print calc(13, 4). ", ";

は
・calc(13, 4) を呼び出し、戻り値を受け取る
・上述で受け取った戻り値に、文字列 ", " を連結する
・連結した文字列を print で出力する

という処理になるのですが。

今回は calc(13, 4) の実行で例外が投げられ\るため、
・calc(13, 4) を呼び出したところで、例外が投げられる
・例外が投げられたため、文字列 ", " の連結は実行されない
・同様に、print による出力も実行されない

となります。

全体を整理してみましょう。

【A】 throw
【B】 catch
【C】 getMessage()

選択肢でこのようになっているのは選択肢5であるため、正解は選択肢5となります。

PHP8初級試験と公式問題集に興味がある方は、以下のページをご覧のうえ、この機会に是非受験ください。

PHP8初級試験
https://www.phpexam.jp/summary/novice8

公式問題集:PHP8技術者認定初級試験公式問題集A
Kindle版 https://amzn.asia/d/1bS88y9
ペーパーバック版 https://amzn.asia/d/3P3Izeu

また、試験対策セミナーは毎月開催しています。興味がある方は以下のページをご覧いただき是非セミナーにもご参加ください。(フォローいただけるとセミナーのご案内が届くようになります)

PHP技術者認定機構の公式Peatixグループ
https://peatix.com/group/43424

www.phpexam.jp

この記事が気に入ったら
いいね または フォローしてね!

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