こんにちは。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

