
PHP8 上級/準上級試験の認定模擬問題として、プライム・ストラテジー様のPRIME STUDYが認定されているようです。ただ、この模擬問題には解説がありませんので解説をまとめていこうと思います。シリーズ第2回目です。

PHP初級レベルから脱却して中級/上級レベルにいきたい人にピッタリの内容ですね。
PRIME STUDY認定模擬問題のリンクはこちらです → https://study.prime-strategy.co.jp/
問題文
PHPの変数の型についての記述で、誤っているものを1つ選びなさい。
なお、すべてのコードの先頭には下記のコードが書かれているものとする。
declare(strict_types=1);
error_reporting(-1);
下記はマニュアルから一部引用した内容である。
usort ( array &$array , callable $callback ) : bool
(1)
整数型 (integer) は整数 ({…, -2, -1, 0, 1, 2, …} という集合) を扱う。
整数のサイズはプラットフォームに依存するが、-2,147,483,648 ~ 2,147,483,647 (32 bit符号付) または -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 (64 bit符号付) である事が多い。
integer 型の範囲外の数を指定した場合、float として解釈されるため、用途と環境によっては注意が必要である。
(2)
コールバック (callback) は PHP 5.4 以降では callable タイプヒントと呼ばれていた。
これには、あらゆるビルドイン関数、ユーザ定義関数、メソッド、静的なクラスメソッドが指定できるが、言語構造 (例:echo や empty、isset 等) は指定が出来ない。
コールバックに「オブジェクトのメソッド」を指定する場合、 配列の 0 番目の要素にオブジェクトを、 そして 1 番目の要素にメソッド名を指定する必要がある。
静的なクラスメソッドを指定する場合は、配列の 0 番目の要素にクラス名を、1 番目の要素にメソッド名を指定する必要がある。或いは ‘ClassName::methodName’ という形式で指定してもよい。
コールバック (callback) が使われる関数には usort() 関数がある。
そのため、以下のコード
class Hoge {
public static function sort($a, $b) {
return $a <=> $b;
}
}
class Foo {
public function sort($a, $b) {
return $a <=> $b;
}
}
$awk = [3, 1, 2];
usort($awk, [Hoge::class, 'sort']);
var_dump($awk);
$awk = [3, 1, 2];
usort($awk, 'Hoge::sort');
var_dump($awk);
$awk = [3, 1, 2];
usort($awk, [new Foo(), 'sort']);
var_dump($awk);
は正しく実行でき、結果は次のとおりとなる。
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
(3)
浮動小数点数 (float / double) は、小数を扱う。
浮動小数点数には精度があり、PHP では通常 IEEE 754 倍精度フォーマットが使われる。
浮動小数点数はどうしても誤差を考慮する必要があるため、例えば「小数を直接比較して等しいかどうかを調べてはいけない」という事を理解する必要がある。
そのため、以下のコード
if (0.3 === (0.1 + 0.2)) {
echo "=>ここにはならない";
} else {
echo "=>こちらになる";
}
を実行すると、
=>こちらになる
という結果が返る。
(4)論理型 (boolean) は「真偽値」とも呼ばれ、値は、true か false か null のいずれかになる。
なお、true、false、null の文字は、大文字で書いても小文字で書いてもよい。
解説
選択肢1
正しいです。
整数型の範囲についての記述や、範囲外の数が float として解釈されます。
整数型(integer)は、小数点を含まない数 のことを指します。例えば、以下のような数はすべて整数型です。
-2, -1, 0, 1, 2, 100, 99999
一方、小数が含まれる数(例:3.14, -0.5)は整数型ではなく、浮動小数点数(float) になります。
自環境で扱える整数の範囲は、PHP_INT_MAX や PHP_INT_MIN で知ることができます。
echo PHP_INT_SIZE,"\n";
echo PHP_INT_MAX,"\n";
echo PHP_INT_MIN,"\n";
// 出力結果
// 8
// 9223372036854775807
// -9223372036854775808
もし 整数の最大値や最小値を超えた数 を使おうとすると、PHPは自動的にその数を 浮動小数点数(float) として扱います。
echo PHP_INT_SIZE + 1
// 出力結果
// 9.2233720368548E+18
選択肢2
正しいです。
callable は、「呼び出し可能なもの」 を指すデータ型です。簡単に言うと、関数のように実行できるもの を変数として扱うことができます。
選択肢のコードは、usort() 関数を使って配列を並べ替える実例です。usort() は、カスタムの比較関数を使って配列の要素を並び替える関数です。
まず、2つのクラス Hoge と Foo を作成しています。
Hogeクラスではsort() という 静的メソッド(static method) を定義しています。
class Hoge {
public static function sort($a, $b) {
return $a <=> $b;
}
}
「return $a <=> $b;」というのは宇宙船演算子 <=> を使った比較演算をしています。これは$a が $b より小さいなら -1、等しいなら 0、大きいなら 1 を返すというものです。つまり、この関数を usort() に渡すと 昇順(小さい順) に並び替えられます。
宇宙演算子<=>はsortの文脈でよく出てくるので覚えておきましょう。
一方、Fooクラスではsort() を インスタンスメソッド(static なしの通常メソッド) として定義してます。
class Foo {
public function sort($a, $b) {
return $a <=> $b;
}
}
ここまでで、定義されているクラスについて把握しました。次にusort()の部分を見てみましょう。
usort($array, callable)について
usort() は、第一引数に処理対象の配列(array型)、第二引数に比較用の関数(callable 型) を受け取ります。比較用の関数は 2つの値を受け取り、その大小を判定するような関数でなければなりません。例えば以下のような無名関数を使った形を見るとわかりやすいかと思います。
usort($awk, function($a, $b) {
return $a <=> $b;
});
問題文のコードの解説
$awk = [3, 1, 2];
usort($awk, [Hoge::class, 'sort']);
var_dump($awk);
Hoge::class は “Hoge” というクラス名を表します。[Hoge::class, ‘sort’] は “Hoge::sort” を表す callable の書き方です。usort() に渡すことで Hoge::sort() が呼ばれ、配列 [3, 1, 2] が 昇順(1, 2, 3) に並び替えられます。
$awk = [3, 1, 2];
usort($awk, 'Hoge::sort');
var_dump($awk);
これは “Hoge::sort” という 静的メソッドを直接指定する書き方で、結果は前述のパターンと同じものになります。
$awk = [3, 1, 2];
usort($awk, [new Foo(), 'sort']);
var_dump($awk);
[new Foo(), ‘sort’] は Foo クラスのインスタンスの sort メソッドを指定する書き方です。インスタンスメソッドを callable として渡す場合、この書き方を使います。これも sort() を適用するので、結果は 昇順(1, 2, 3)となります。
どの書き方も 同じ並び順(1, 2, 3) になります。すべての usort() が sort() メソッドを正しく適用できます。
選択肢3
正しいです。
PHP では通常 IEEE 754 倍精度フォーマットが使われます。
float型は浮動小数点数で、誤差があります。比較方法には緩やかな比較(==)と厳密な比較(===)がありますが、どちらを使ってもうまく比較ができないので注意しましょう。
選択肢4
誤りです。PHPの論理型(boolean)は、true または false のいずれか です。「null」も値として含む、という記述は誤りです。null は論理型ではなく、独立したnull型として扱われます。
正解選択肢
以上より選択肢4が正解となります。
コメント