Shoeisha Technology Media

IT人材ラボ

注目の特集・連載

【PHP技術者】関数の命名規則、適切な出力文字エスケープ関数、フィルタ関数の動作ほか

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加

 PHPに関して身に付けた知識やスキルを評価し認定する試験「PHP技術者認定試験」(運営:一般社団法人 PHP技術者認定機構)。本連載ではその模擬問題を10問出題します。出題は、PHPプログラミングの基本から、開発中に経験したり、書籍やWebなどで積極的に知識を得たりしないと正解できない応用まで。初級者も上級者もぜひトライしてください!

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対策としては不適切です。

〔正解:24

[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]

〔正解:14

[2]: 「1つ以上の要素を配列の最後に追加する」関数はarray_push()です。

※印刷用ページ表示機能はメンバーのみが利用可能です(登録無料)。

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • 古庄 道明(寺子屋/格子組)(フルショウ ミチアキ)

    1970年浅草生まれ 1995年に富士通系のソフトハウスに就職しプログラマに転身。1999年個人事業主として独立し現在に至る。「寺子屋」「格子組」といったエンジニア支援活動を独自に展開し、占い師時代の「ガルーダ」という占い師名にちなんだ「がる先生」の愛称で親しまれている。 コンサルティングからシステム設計、ネットワークにセキュリティと、守備範囲は比較的多岐に渡る。「技術の基本は、その技術がない時の“困ってる”が根っこ」をモットーに、古い話から現代へ歴史をたどるように教えるのが持ち味。

IT人材ラボ
2016/01/08 23:03 /article/detail/12
All contents copyright © 2017-2019 Shoeisha Co., Ltd. All rights reserved. ver.1.0