PHPプログラミング診断室

第2回 HTMLとPHPの見事なハーモニー(治療編)

この記事を読むのに必要な時間:およそ 6.5 分

治療ポイント1. コードの分離

まず,コードの構成を,設定,ロジック,ビューの3段階に分離しました。こうして分離しておくことで,それぞれの役割が明確になり,見通しの良いコードとなります。また,別ファイルで同じ記述を共有したい場合(設定などは多くの場合そうなります)⁠設定部分のみを別ファイルに切り出して,それぞれのPHPファイルでは設定ファイルをrequire_once文で読み込むということもやりやすくなります。

それぞれの部分について解説すると,設定ではdefine文を使って,設定値を定数として定義しています。こういった設定値はコードの中で変更するということはあまりないので,定数として定義しておくと「これは変更されない値だ」ということが明確になります。コードの中には数多くの値が登場するので,変更すべき値と変更しない値を区別するということも読みやすいコードを書くうえで大切になります。

ロジック部分では,まず関数定義を行い,そのあとにメインの処理を書いています。メイン処理は130行目から始まるのですが,わずか20行強と短くなっています。この中で,状態による分岐を行い,フォームからの投稿(POST)の場合は,doPost()関数を実行してます。元のコードでは,switch文にて条件分岐を行い,その中のcase文の中で実際の処理を記述していたのですが,ここでは条件分岐と実際の処理を分離することで,どのような状態があり,どのような流れになるのかがはっきりとわかるようになっています。

そして,最後がHTMLを出力するビューです。基本的にはHTMLの記述を行い,動的にHTMLの出力を行う個所のみ,必要なPHPを入れるようにしています。HTMLの出力はprint文をやめて,HTMLはそのままHTMLとして記述しています。元のコードよりかなり見やすくなったのではないでしょうか。

治療ポイント2. コードの簡素化

主にロジック部分になりますが,処理の見直しを行い,コードを簡素化していきました。

元のコードでは,$mode変数で実行する処理を分岐していたのですが,実際はこの$modeには2つの状態しかなく,それも「フォームを表示する場合」⁠フォームから値が送信されてくる場合」の2種類しかないため,$_POSTに値がない場合は前者,ある場合は後者として扱うことで$mode変数自体をなくしました。

ほかには,各処理を関数化することで,関数内に処理を閉じ込めています。たとえば,元のコードではswitch文とbreak文をうまく(?)組み合わせて,エラー発生時に処理から抜けるというコードが多数あったのですが,関数にしたことで,素直にreturn文で実装しています。

治療ポイント3. 今のPHPの書き方へ

2013年の今,このPHPコードを直すならということで,一部処理については,昨今のPHPでの書き方に変えています。

まずはDB処理について。今ではPDO(PHP Data Objects)を利用するのが一般的となっていますので,pg_*関数はPDOを使った書き方に変えています。SQL文を実行する際は,利便性とセキュリティを考慮してプリペアドステートメントを利用しています。これも今の定石と言ってよいでしょう。

ほかには,現在時刻を得るのにDateTimeクラスを,PDOでのエラーハンドリングにて例外を,また配列の定義にてarray()ではなく[](short array syntax)を利用しています。

治療ポイント4. Noticeへの対応

元のコードを実行すると,未定義定数の参照や連想配列に存在しないキーを参照したためにNoticeエラーが多数発生しています。Noticeエラーは警告が表示されるだけで,実行には影響がないのですが,こうした警告を無視することは,せっかくPHPが発した情報を無視することになり,本来修正すべき点を見落とすことになります。

修正コードでは,定数はちゃんとdefine文について定義し,配列ではarray_key_exists()関数にてキーの存在を確認してから参照するようにしています。

治療ポイント5. セキュリティへの配慮

SQLインジェクションやクロスサイトスクリプティング(XSS)といった攻撃に対する対応を行っています。SQLインジェクションに対してはプリペアードステートメントの利用,XSSに対してはhtmlspecialchars()関数によるエスケープを行っています。htmlspecialchars()関数の実行はビューの中では何度となく出てくるので,escapeHtml()関数にまとめてしまって,変数を出力する場面ではこの関数を呼ぶようにしています。

まとめ

第1回と第2回では,2002年とかなり古いPHPコードについて見てきました。2013年の今では新規でこういったコードを書くということはないと思うのですが,まだまだひっそりと稼働していて,いつこういったコードにお目にかかるやもしれません。

このコードはある意味すごいです。関数にまとめたり,ロジックとビューの分離を行わずによくこのコードを書いたと感心します。このコードを読んですぐに動作イメージを描けるのならば,それはそれですごいのですが,誰もが理解しやすいコードにしておくことで,不具合の発見も気づきやすく,変更にも強いコードとなります。

修正コードはあくまで一例で,まだまだ手を加えていくことができます。特にビューについては本来別画面となる内容(フォーム画面と完了画面)を1ファイルに混在させているので,見通しが悪くなっています。ほかにも以下に挙げるように,手を入れるべき個所はいくつかあるのですが,それらは読者への課題としてみたいと思います。

  • フォーム画面と完了画面とでファイルを分ける
  • 設定,ロジック,ビューでファイルを分ける
  • ライブラリやフレームワークの活用

初めての診断はいかがだったでしょうか。今後もこのような流れで,巷にある悩めるPHPコードを診断していきます。あなたの周りにあるPHPコードの投稿もお待ちしています。

診断を要するPHPプログラム大募集!

本連載では,みなさんからのPHPコードの提供を募集しています。仕事の現場で実際に目撃したり,若気の至りで生み出した秘蔵のお宝コードなどをぜひ投稿してください。 採用された方にはQUOカード3000円分を差し上げます。応募はこちらのページから。

著者プロフィール

新原雅司(しんばらまさし)

1×1株式会社 代表取締役

大阪でPHPを駆使してWebシステムの開発を行う日々。MotoGPをこよなく愛す。愛車はPCX。

Twitter:shin1x1
blog:Shin x blog