Contents
「第1回 PHP 8 上級 模擬試験」を解説していきます
本記事ではひたすら下記記事の模擬試験の解説をしていきたいと思います!
第1回 PHP 8 上級 模擬試験
https://study.prime-strategy.co.jp/study/ph8ex1/
解説記事一覧
- 【php8上級/準上級試験】模擬問題解説 問題1.~ 3. abstract staticメソッド
- 【php8上級/準上級試験】模擬問題解説 問題4. __construct() __destruct __call() __callStatic()
- 【php8上級/準上級試験】模擬問題解説 問題5. __toString() 「例外を投げる(throw new \Exception)とは?」 __invoke() __get() __debugInfo()
- 【php8上級/準上級試験】模擬問題解説 問題6. &参照(リファレンス)unset()
- 【php8上級/準上級試験】模擬問題解説 問題7. 名前空間とグローバル空間 use エイリアス(as)
- 【php8上級/準上級試験】模擬問題解説 問題8. error_reporting set_error_handler() 例外捕捉
- 【php8上級/準上級試験】模擬問題解説 問題9. interface implements
- 【php8上級/準上級試験】模擬問題解説 問題10. SPL RecursiveDirectoryIterator RecursiveIteratorIterator SplFileInfo SplFileObject
- 【php8上級/準上級試験】模擬問題解説 問題11. $_SERVER
模擬問題 5
メソッドに関する説明の中で、誤っているものを1つ選びなさい。
なお「\
」はバックスラッシュに読み替えること。
また、すべてのコードの先頭には下記のコードが書かれているものとする。
declare(strict_types=1);
error_reporting(-1);
__toString() メソッドにより、クラスが文字列に変換される際の動作を決めることができる。
そのため、以下のコード
class Hoge {
public function __toString() {
return $this->s;
}
private $s = 'string';
}
$obj = new Hoge();
echo 'object: ' . $obj , PHP_EOL;
は正しく実行でき、結果は object: string となる。
また、__toString() メソッドで例外を投げる事は、PHP 7.3 までは出来なかったが、PHP 7.4 からは出来るようになった。
そのため、以下のコード
class Hoge {
public function __toString() {
throw new \Exception('*** test string ***');
}
private $s = 'string';
}
try {
$obj = new Hoge();
echo 'object: ' . $obj, PHP_EOL;
} catch(\Throwable $e) {
echo $e->getMessage(), PHP_EOL;
}
を実行すると *** test string *** となる。
__toString()について
__toString() メソッドは、「オブジェクトを文字列として扱うときに、どんな文字列にするか」を決めるメソッドです。
例えば、echo したりするときに、このメソッドが自動で呼び出されます。
そのうえで、「PHP 7.4 以降は __toString() でも例外を投げられる」ようになりました。
例外を投げる(throw new \Exception)とは?
プログラムを強制的に中断させます
throw new \Exception('エラーメッセージ');
echo 'not finished';
// 出力結果
PHP Fatal error: Uncaught Exception: エラーメッセージ
通常は try / catch ブロックでエラーハンドリングをします!
tryの中で例外を投げられるとtryブロックの残りの処理はスキップされcatchブロックにジャンプします
try {
throw new \Exception('エラーメッセージ');
} catch(\Throwable $e) {
echo $e->getMessage();
}
echo ' not finished';
//出力結果
エラーメッセージ not finished
問題文では下記の流れで例外がキャッチされます
- $obj を 文字列として扱おうとしている
- __toString() が 自動的に呼ばれる
- __toString() の中で throw new \Exception(‘*** test string ***’); を実行
*** test string ***
よって選択肢は⭕です
__invoke() メソッドは、 スクリプトがオブジェクトを関数としてコールしようとした際にコールされる。
そのため、以下のコード
class Hoge {
public function __invoke() {
var_dump($this);
return 'string';
}
}
$obj = new Hoge();
$r = $obj();
var_dump($r);
は正しく実行でき、結果は次のとおりとなる。
object(Hoge)#1 (0) {
}
string(6) "string"
__invoke() メソッド
__invoke() メソッドは、 スクリプトがオブジェクトを関数としてコールしようとした際にコールされます。
なので問題だと$objはオブジェクトですが、$obj();関数として呼び出されているので__invokeが呼び出されます
⬇️
var_dump($this)の処理について
そもそも$thisとは
$thisは現在のオブジェクトインスタンスを指す特別な変数
var_dumpでオブジェクトを出力するときのフォーマット
object(クラス名)#オブジェクトID (プロパティの数) { プロパティの内容 }
class Test {}
$obj = new Test();
var_dump($obj);
// 出力: object(Test)#1 (0) { }
var_dumpで文字列を出力するときのフォーマット
object(クラス名)#オブ$str = "hello";
var_dump($str);
// 出力: string(5) "hello"ジェクトID (プロパティの数) { プロパティの内容 }
となるので問題文の通りの出力結果となり選択肢は⭕です
__get() は、アクセス不能 (protected または private) または存在しないプロパティからデータを読み込む際に使用する。
__getStatic() は存在せず、オブジェクトのコンテキスト、静的コンテキストのどちらでも動く。
そのため、以下のコード
class Hoge {
public function __get(string $name) {
return "not exist {$name}";
}
}
$obj = new Hoge();
echo $obj->test, PHP_EOL;
echo Hoge::$test2, PHP_EOL;
は正しく実行でき、結果は次のとおりとなる。
not exist test
not exist test2
__getメソッドとは
__get は下記のケースでアクセスしようとした際に呼び出されます(データを読み込もうとしたとき)
問題文で「静的コンテキストのでも動く」とありますが、間違ってます
Hoge::$test2のような静的なアクセスの場合は__getは呼び出されません。
このようなアクセスではエラーが発生します。
よって選択肢は誤り❌です
__debugInfo() メソッドが実装されていると、var_dump() でオブジェクトをダンプするときに出力するプロパティの情報を制御できる。
そのため、以下のコード
class Hoge {
public function __debugInfo() {
return [
's' => $this->s,
'i' => $this->i,
];
}
private $pass = 'password';
private $s = 'string';
private $i = 999;
}
$obj = new Hoge();
var_dump($obj);
は正しく実行でき、結果は次のとおりとなる。
object(Hoge)#1 (2) {
["s"]=>
string(6) "string"
["i"]=>
int(999)
}
__debugInfo()とは
var_dump()
が呼ばれた時のオブジェクトの出力を制御するために使用します。
問題文のようにセキュリティ上重要な情報(パスワードなど)を隠し、表示したい情報だけを選んで返せます!
__debugInfo()がない場合は、アクセス可能なすべてのプロパティが表示されます。
よって選択肢は⭕です