「PHP技術者認定試験」対応の模擬試験問題です。レベルは、初級から準上級、上級までまぜまぜ! 寺子屋/格子組の古庄道明からの出題、チャレンジしてみてください。
問題1~5
問題1|PHP5準上級:関数名の規則の出題
次の選択肢はいずれも関数名である。選択肢のうち、PHPの規約上エラーになる関数名を1つ選べ。 なお、マルチバイト文字は「UTF-8である」とする。
- 1. hoge-foo()
- 2. _0123()
- 3. 関数()
- 4. hoge()
解答・解説
PHPの関数名は、次のとおりです。
- 先頭1文字目が「文字またはアンダースコア」で始まり、
- 2文字目以降が「文字または数字またはアンダースコア」
そのルールを正規表現で表すと「[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
」となります。
正規表現に「\x7f-\xff
」とあるために、文字コードがUTF-8であれば、マルチバイト文字を使うことも可能です。そのために3番はエラーになりません。
一方、記号で許されているのは「アンダースコア」のみになるために、ハイフンを使っている1番は、syntax errorとなります。
〔正解:1〕
問題2|PHP5上級:アプリケーションに関するテクニックの出題
次の選択肢はいずれも「出力バッファリング関数」を用いた記述である。選択肢のうち「プログラム途中のechoによる出力が適切に出力される」ものを1つ選べ。なお、php.iniのoutput_bufferingはoffになっているものとする。
-
1.
ob_start(); echo 'test'; ob_end_flush();
-
2.
ob_start(); echo 'test'; ob_end();
-
3.
ob_start(); echo 'test'; ob_end_clean();
-
4.
ob_start(); echo 'test'; ob_clean();
解答・解説
出力バッファリングは「ob_start()
関数を呼ぶことで有効」になります。
1番は最もベーシックな使い方の1つで、適切に出力をバッファリングすることができるので、この選択肢が正解となります。
2番に書かれている「ob_end()
」という関数は、PHPの提供関数には存在しないので誤りです。
3番、4番はいずれも「バッファリングの内容を消す」命令で、「echo 'test';
」の出力内容が消されてしまうために、誤りです。
〔正解:1〕
問題3|PHP5上級:セキュリティのうち、出力文字エスケープの出題
「ユーザから入力された文字」など、外部由来の文字列を適切にエスケープ処理せずに出力すると、XSS(cross site scripting:クロスサイトスクリプティング)という脆弱性になる。次の選択肢のうち、XSSを防ぐためのエスケープ用関数として適切なものを2つ選べ。
- 1. strip_tags()
- 2. htmlspecialchars()
- 3. html_entity_decode()
- 4. htmlentities()
解答・解説
外部に起因する文字列をそのまま出力するとXSSという脆弱性をうむので、適切に出力文字をエスケープする必要があります。選択肢にある関数のうち、htmlspecialchars()
およびhtmlentities()
は、そのエスケープを適切に行ってくれます。故に、正解は2番と4番となります。
なお、正解の2つの関数のうち、htmlspecialchars()
のほうがエスケープ対象の文字種類が少なく(現時点でマニュアルに書かれている変換対象文字は5種類)、htmlentities()
のほうがたくさん(200種類以上)の文字をエスケープしてくれます[1]。しかし、セキュリティの文脈で考えた場合は差異がないので、どちらを用いてもよいでしょう。どちらかというと、日本国内ではhtmlspecialchars()
を目にする頻度が高いように思われます。
1番のstrip_tags()
は「HTMLタグおよびPHPタグを取り除く」関数ですが、これだけではXSSを防げないために、不適切です。
3番のihtml_entity_decode()
は「HTMLエンティティを適切な文字に変換する」関数で、「文字をHTMLエンティティに変換する」関数であるhtmlentities()
やhtmlspecialchars()
と対になる関数であるために、XSS対策としては不適切です。
〔正解:2と4〕
注
[1]: 変換対象文字に興味がある時は、get_html_translation_table()
を動かしてみるとよいでしょう。
問題4|PHP5準上級:遅延静的束縛(Late Static Binding)の出題
以下のプログラムを実行したときに、適切な出力結果を1つ選択せよ。
<?php class hoge { public static function base() { echo "call hoge's base\n"; } public static function test1() { self::base(); } public static function test2() { static::base(); } } // class foo extends hoge { public static function base() { echo "call foo's base\n"; } } // hoge::test1(); hoge::test2(); foo::test1(); foo::test2();
-
1.
call hoge's base call foo's base call hoge's base call foo's base
-
2.
call hoge's base call hoge's base call hoge's base call foo's base
-
3.
call hoge's base call hoge's base call hoge's base call hoge's base
-
4.
call hoge's base call hoge's base call foo's base call foo's base
解答・解説
遅延静的束縛(Late Static Binding)の問題です。
PHP 5.2までは、self
を使って「自分自身」という呼び方(転送コール)しかありませんでしたが、これは「static
(静的)なクラスを継承したとき」に問題がありました。端的には、self
は「該当メソッドが記述された(該当メソッドが属する)クラス」として解決され、static
は「最初にコールされたクラスを参照する」ように動きます。
したがって、
hoge::test1();
→ self::base();
→(test1
メソッドはhoge
クラスに書かれているので)hoge::base();
hoge::test2();
→ static::base();
→(hoge::
でcall
されているので)hoge::base();
foo::test1();
→ self::base();
→(test1
メソッドはhoge
クラスに書かれているので)hoge::base();
foo::test2();
→ static::base();
→(foo::
でcall
されているので)foo::base();
がそれぞれcall
されることになります。
そのため、選択肢2番の出力がこのプログラムでの「正しい出力結果」となり、本問の正解になります。
〔正解:2〕
問題5|PHP5初級:配列の出題
以下のコードによって作成される、2つの要素をもつ配列がある。
<?php $array_wk = array('1st', '2nd');
この配列に3つ目の要素を付け加えるために適切なコードを2つ選択せよ。
- 1. $array_wk[] = ‘3rd’;
- 2. $array_wk = $array_wk + ‘3rd’;
- 3. array_pop($array_wk, ‘3rd’);
- 4. $array_wk[count($array_wk)] = ‘3rd’;
解答・解説
本問で取り上げているのは、配列の基本的な操作の1つです。最も簡単なのは1番の書き方で、通常の数値添字の配列で「要素の最後に新規要素を追加」する場合に、実際の実務でもよく用いられます。
4番は少し面倒な書き方ですが、追加する配列が今回のように「0から始まり、飛び番のない添え字のみの配列」の場合は、
-
count
で得られる数は「配列の要素数」である - 数値添え字は「0から始まり、飛び番のない添え字」であると仮定すると、必ず「0から(要素の数 - 1)まで」である
ことから、「次に追加する数値添え字の数」はcount
の戻り値(配列の要素数)と等しいので、このような書き方でも追加が可能です。
一方で、2番のような「配列と数値の加算」は、「Fatal error: Unsupported operand types
」というエラーを発生させます。また、3番で使われているarray_pop()
は「配列の末尾から要素を取り除く」関数であるために、今回のような「配列の最後に新規要素を追加する」状況では不適切です[2]。
〔正解:1と4〕
注
[2]: 「1つ以上の要素を配列の最後に追加する」関数はarray_push()
です。