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

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

目次

問題

関数に関する次の記述のうち誤っているものはどれか。

選択肢

選択肢1
PHPエンジンはプログラムファイル全体を読み込み、ファイル内のコマンドを実行する前に関数定義を処理する。そのため通常のユーザ定義関数は呼び出しの前でも後でも定義することができる。

選択肢2
関数宣言で指定するパラメータのデフォルト値は、リテラルのほか変数にすることもできる。

選択肢3
複数のパラメータをとる関数において、デフォルト値付きパラメータはすべての必須パラメータの後に記述すべきである。

選択肢4
関数名は変数名と同じ規則に従う。関数名は文字、アンダースコアから開始し、2番目以降は文字、数字、アンダースコアを使うことができる。

選択肢5
一つのreturn命令文は一つの値しか返せない。カンマ区切りにして複数の値を返すようなことはできない。関数から2つ以上の値を返したい場合には一つの配列に複数の値を入れてその配列を返すとよい。

回答と解説

問題は「関数について」です。
https://www.php.net/manual/ja/language.functions.php
に一通り記載があるので、確認をしておくとよいでしょう。

プログラム言語によっては、関数は「使われるよりも前に宣言される」必要があります。
しかしPHPは「関数は参照される前に定義されている必要はありません」とマニュアルにも明記されています。
https://www.php.net/manual/ja/functions.user-defined.php
(ただし「条件つきの関数」と「関数の中の関数」は、実際に定義されるまでは呼び出すことができないので注意が必要です)
そのため、選択肢1の「関数は呼び出しの前でも後でも定義することができる。」は、正しいことが書かれています。

選択肢2に行く前に、簡単に用語を二つ説明しておきましょう。
まず、リテラルとは、プログラムの中に直接書かれた「値そのもの」です。
例えば “PHP World” は「文字列リテラル」、123456 は「整数リテラル」、といった言い方をします。

次に、関数の引数とパラメータについてです。
関数定義に書く「関数の定義側で値を受け取るための変数」をパラメータ、「関数を呼び出す側で実際に渡す値」を引数、と呼びます。

PHPは、パラメータにデフォルト値を指定することができます。
https://www.php.net/manual/ja/functions.arguments.php#functions.arguments.default
デフォルトパラメータの値には、スカラー値、配列、および特殊な型 null を指定できます(試験の範囲外となりますが、PHP 8.1.0 以降では、new ClassName() 記法を使ってオブジェクトも指定できます)。
また、マニュアルには「デフォルト値は、定数式である必要があり、(例えば)変数やクラスのメンバーであってはなりません」と明記されています。
そのため、選択肢2の「パラメータのデフォルト値は、リテラルのほか変数にすることもできる」は、誤りになります。

デフォルト値を有するパラメータは、デフォルト値がないパラメータの右側に全てある必要があります。
マニュアルにも「デフォルト値を有するパラメータは、 デフォルト値がないパラメータの右側に全てある必要があることに注意して下さい。 そうでない場合、デフォルト値を指定していても、 呼び出し時に省略できません」とあります。

function formatPrice($currency = 'JPY', $amount) {
    return "{$amount} {$currency}";
}
echo formatPrice(980);

というコードを書いて動かした場合、引数の980は$amountではなく、$currencyに入ってきます。
そのため大まかには
・Deprecatedとして「デフォルト値付きパラメータが必須パラメータより前に宣言されている」旨のメッセージ
$amount に対応する引数が渡されていないため、引数が不足している旨
のエラーが出力されます。

試験対象のPHP 8.0だと

Deprecated: Required parameter $amount follows optional parameter $currency in ...
Fatal error: Uncaught ArgumentCountError: Too few arguments to function formatPrice(), 1 passed in ...

となります。

参考ですが、PHP 8.1以降では、先に書かれた $currency も暗黙的に必須パラメータとして扱われます。
そのため、PHP 8.1からPHP 8.3までだと

Deprecated: Optional parameter $currency declared before required parameter $amount is implicitly treated as a required parameter in ...
Fatal error: Uncaught ArgumentCountError: Too few arguments to function formatPrice(), 1 passed in ...

PHP 8.4とPHP 8.5だと

Deprecated: formatPrice(): Optional parameter $currency declared before required parameter $amount is implicitly treated as a required parameter in ...
Fatal error: Uncaught ArgumentCountError: Too few arguments to function formatPrice(), 1 passed in ...

となります。

そのため「複数のパラメータをとる関数において、デフォルト値付きパラメータはすべての必須パラメータの後に記述すべきである」の記述は正しいので、選択肢3は正しいことが書かれています。

関数名は変数名と同様に「まず文字かアンダースコアで始まり、その後に任意の数の文字・数字・あるいはアンダースコアが続く」というルールがあります。
https://www.php.net/manual/ja/functions.user-defined.php
そのため「関数名は文字、アンダースコアから開始し、2番目以降は文字、数字、アンダースコアを使うことができる」の記述は正しいので、選択肢4は正しいことが書かれています。

PHPの戻り値は「配列やオブジェクトを含むあらゆる型を返すことができます」が、一方で「関数は複数の値を返すことはできません」。ただし「配列を返すことで似たような結果を得ることができます」。
そのため「一つのreturn命令文は一つの値しか返せない。カンマ区切りにして複数の値を返すようなことはできない。関数から2つ以上の値を返したい場合には一つの配列に複数の値を入れてその配列を返すとよい」の記述は正しいので、選択肢5は正しいことが書かれています。

上述で誤った記述があるのは選択肢2のため、正解は選択肢2です。

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をコピーしました!
目次