if 文, switch 文を使わない条件分岐
入門書にはレベルが高く、解説している本はないが、知っていて絶対損はしないテクニック。
このテクニックの代表例はPHPプログラマーの間で知らない人はいないであろう PEAR::DB 。( factory メソッドで使用されています。)
では、さっそく。
【お題】
運命をリクエスト変数として受け取り、運命に応じ、何らか処理をするアプリケーション
<?php /** * ありがちなパターン( switch 文も同様 ) * => ソースを丁寧に読んでも何の意味もありません、ざっと流し読みして下さい。 */ $omikuji = $_REQUEST['omikuji']; if ($omikuji == 'daikichi') { include('includes/daikichi_class.php'); $object = new daikichi_class(); // -- 運勢に応じた処理(処理) -- // } elseif ($omikuji == 'kichi') { include('includes/kichi_class.php'); $object = new kichi_class(); // -- 運勢に応じた処理(処理) -- // } elseif ($omikuji == 'chukichi') { include('includes/chukichi_class.php'); $object = new chukichi_class(); // -- 運勢に応じた処理(処理) -- // } elseif ($omikuji == 'syouchukichi') { include('includes/syouchukichi_class.php'); $object = new syouchukichi_class(); // -- 運勢に応じた処理(処理) -- // } elseif ($omikuji == 'kyou'){ include('includes/kyou_class.php'); $object = new kyou_class(); // -- 運勢に応じた処理(処理) -- // } elseif ($omikuji == 'daikyou') { include('includes/daikyou_class.php'); $object = new daikyou_class(); // -- 運勢に応じた処理(処理) -- // } else { die('運勢に対応するクラスがありません。人としての道を踏み外してませんか?'); } ?>
これを if 文, switch 文を使わない条件分岐テクニックを使うと以下。
<?php /** * スッキリパターン */ $omikuji = $_REQUEST['omikuji']; $classname = $omikuji.'_class'; @include('includes/' . $classname . '.php'); if (!class_exists($classname)) { die('運勢に対応するクラスがありません。人としての道を踏み外してませんか?'); } $object = new $classname(); // -- 運勢に応じた処理(処理) -- // ?>
条件分岐する回数が多いときは、美しくて、効率もよく、一石二鳥。
[ 追記 ]
リクエスト変数をもとにファイルを include(require)することは、実装方法によっては重大な脆弱性につながるので、一般ユーザー向けに公開する場合には注意が必要です。(関連用語:パストラバーサル, ディレクトリトラバーサル)