【やさしく解説】PHP8上級試験の模擬問題(26)

PHP
スポンサーリンク

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

PHP初級レベルから脱却して中級/上級レベルにいきたい人にピッタリの内容ですね。

PRIME STUDY認定模擬問題のリンクはこちらです → https://study.prime-strategy.co.jp/ 

問題文

関数 に関する説明の中で、誤っているものを1つ選びなさい。
なお「\」はバックスラッシュに読み替えること。
また、すべてのコードには下記のコードが適切な箇所に書かれているものとする。

declare(strict_types=1);
error_reporting(-1);
下記はマニュアルから一部引用した内容である。

htmlentities ( string $string , int $flags = ENT_COMPAT , string|null $encoding = null , bool $double_encode = true ) : string
htmlspecialchars ( string $string , int $flags = ENT_COMPAT , string|null $encoding = null , bool $double_encode = true ) : string

ENT_COMPAT ダブルクオートは変換しますがシングルクオートは変換しません。
ENT_QUOTES シングルクオートとダブルクオートを共に変換します。
ENT_NOQUOTES シングルクオートとダブルクオートは共に変換されません。

trim ( string $string , string $characters = ” \n\r\t\v\0″ ) : string
ltrim ( string $string , string $characters = ” \n\r\t\v\0″ ) : string
rtrim ( string $string , string $characters = ” \n\r\t\v\0″ ) : string

strpos ( string $haystack , string $needle , int $offset = 0 ) : int|false
文字列 haystack の中で、 needle が最初に現れる位置を探します。
返り値
needle が見つかった位置を、 haystack 文字列の先頭 (offset の値とは無関係) からの相対位置で返します。 文字列の開始位置は 0 であり、1 ではないことに注意しましょう。
needle が見つからない場合は false を返します。

(1)
htmlentities() 関数と htmlspecialchars() 関数は、いずれも「文字を HTML エンティティに変換する」。
htmlspecialchars() 関数が「特殊文字」だけであるのに対し、htmlentities() 関数は「適用可能な全ての文字」を変換する。
この関数は、XSS 対策のためのエスケープ処理としてよく使われている。XSS 対策で使う場合、どちらを使ってもよい。
第二引数をデフォルトのままにすると「ダブルクオートは変換するがシングルクオートは変換しない」ので、XSS 対策用には、第二引数を ENT_QUOTES にするとよい。
そのため、以下のコード

$string = '<>&"\'∞';
echo $string, PHP_EOL;
echo htmlspecialchars($string), PHP_EOL;
echo htmlspecialchars($string, ENT_QUOTES), PHP_EOL;
echo htmlentities($string, ENT_QUOTES), PHP_EOL;


を実行すると、結果は次のとおりとなる。

<>&"'∞
<>&"'∞
<>&"'∞
<>&"'∞

(2)
trim() 関数は文字列の先頭および末尾にあるホワイトスペースを取り除く。
また、 文字列の最初から空白 (もしくはその他の文字) を取り除く ltrim() 関数、文字列の最後から空白 (もしくはその他の文字) を取り除く rtrim() 関数もある。
第二引数を指定しない場合は 0x20の空白、0x09のタブ、0x0Aのリターン などが削除されるが、引数を指定すると削除したい文字を指定する事も出来る。
そのため、以下のコード

$string = "\t a b\tc\n";
var_dump( trim($string) );
var_dump( trim($string, "\t\n ac") );


を実行すると、結果は次のとおりとなる。

string(5) "a b c"
string(1) "b"

(3)
ord() 関数は、文字列の先頭バイトを、0 から 255 までの値に変換する。
また chr() 関数は、数値から、1 バイトの文字列を生成する。
そのため、以下のコード

$s = 'abc';
$ascii = ord($s);
var_dump($ascii);

var_dump( chr($ascii) );

$ascii += 5;
var_dump( chr($ascii) );


を実行すると、結果は次のとおりとなる。

int(97)
string(1) "a"
string(1) "f"

(4)
strpos() 関数は文字列内の部分文字列が最初に現れる場所を見つける。
そのため、以下のコード

$fn = function($needle) {
  $string = 'abc';

  if ( strpos($string, $needle) != false ) {
    echo "{$needle} が見つかりました", PHP_EOL;
  } else {
    echo "{$needle} は見つかりませんでした", PHP_EOL;
  }
};

$fn('a');
$fn('z');


を実行すると、結果は次のとおりとなる。

a が見つかりました
z は見つかりませんでした

解説

選択肢1の解説

正解です。
一見、正しく見える内容ですが 出力結果の説明が間違っています。

$string = '<>&"\'∞';
echo $string, PHP_EOL;
echo htmlspecialchars($string), PHP_EOL;
echo htmlspecialchars($string, ENT_QUOTES), PHP_EOL;
echo htmlentities($string, ENT_QUOTES), PHP_EOL;


このコードを順に見ていくと…
(1行目)文字列の出力: <>&”‘∞ がそのまま表示されます。
(2行目)htmlspecialchars($string):第二引数を指定していないので、デフォルトの ENT_COMPAT が使われます。
(3行目)htmlspecialchars($string, ENT_QUOTES):第二引数にENT_QUOTESを指定しています。
(4行目)htmlentities($string, ENT_QUOTES):使える限りすべての文字をエンティティに変換します。

選択肢2の解説

正しいです。
trim() は文字列の 前後 の不要な文字を取り除く関数です。デフォルトでは \t(タブ)や \n(改行)、空白などを削除します。第二引数で削除したい文字を 個別に指定することもできます。

$string = "\t a b\tc\n";


この文字列は、前にタブ \t、後ろに改行 \n などが含まれています。このため、trim($string) の結果は “a b c”となります(先頭と末尾の制御文字が除かれる)。

trim($string, “\t\n ac”) は「\t・\n・空白・a・c」などを 先頭・末尾から削除され、中央の b だけが残ります。

よって出力結果は下記となります。

string(5) "a b	c"
string(1) "b"

選択肢3の解説

正しいです。
ord() は文字列の最初の1文字を ASCII数値に変換します。

ord(‘a’) → 97(a の ASCII コード)
chr(97) → ‘a’(数値 → 文字)
chr(97 + 5) → chr(102) → ‘f’

このように、ASCII コードと文字の変換が可能です。

選択肢4の解説

誤りです。
このコードは一見正しそうに見えますが、strpos() の判定方法が間違っています。

if ( strpos($string, $needle) != false ) {


この判定だと、needle が先頭(位置 0)にある場合に 0 != false が false とみなされてしまうため、見つかっているのに見つかっていないと誤判定されます。

PHPでは、strpos() の返り値が 整数 0(先頭で見つかった)でも、それは false と同じように評価されてしまうため、=== を使って厳密比較する必要があります。

if ( strpos($string, $needle) !== false ) {


これが正しい書き方となります。

正解選択肢

以上より選択肢4が正解となります。

コメント

タイトルとURLをコピーしました