修正コード
第3回目で診断したPHPコードについて、問題点を修正したコードを書いてみましょう。
修正コードのポイントですが、まずコードの書き方については診断編で列挙した個所を修正しています。さらに設計についても見直しを行い、独自で実装しているセッション機能を、PHP標準のセッション機能を使うよう変更しています。最後に今どきのPHPの書き方ということで、名前空間やクラス定数などを盛り込んでいます。
では、治療後の修正コードをどうぞ。
治療ポイント1. コメントをPHPDocに変更
コメントを記号で彩られた元の形からPHPDocに変更しました。これによりグッと今っぽいPHPコードになったのではないでしょうか。コメントは動作には影響しないものですが、コードを読むという意味ではとても大きな役割を果たします。
PHPDoc形式で書かれたコメント部分をDocBlockと言います。下記がaddItem()
メソッドのDocBlockとなります。DocBlockにある@param
タグはメソッドの引数を表しており、addItem()
メソッドには、string型の$itemCode
とinteger型の$count
の2つの引数があることがわかります。また、戻り値を表す@return
タグがないので、このメソッドには戻り値がないことがわかります(戻り値がない場合は、@return void
と表記する場合もあります)。
phpDocumentorというAPIリファレンスを自動生成するツールでこのPHPファイルのリファレンスを生成した例が下記です。
先ほどのaddItem()
メソッドの個所を抜粋しています。DocBlockに記述したコメントやタグが見やすい形式で出力されています。このようにPHPDoc形式でコメントを書くことでこういったツール群の恩恵を受けることができます。
治療ポイント2. ハンガリアン記法からの脱却、メソッド名の見直し
変数名を修正して、ハンガリアン記法から意味のわかりやすい英単語の組み合わせにしました。$a_Item
はアイテムが複数であることを示すように$items
へ、$cGoodsCode
は商品を示す単語をitem
に統一して$itemCode
へ、$iGoodsNum
も同様に$itemCount
へ変更しています。
無駄なプレフィックスがなくなったことで、変数名だけを見ても何を意味するかが明確になり、理解しやすくなっています。前項のPHPDocによるコメントを付けたことで、引数やメンバ変数のデータ型はコメントとして記述しています。
メソッド名についても読みやすいように変更を行いました。いくつかのメソッドではdo_add_item()
のように先頭に「do_」が付いていたのですが、これは不要なので削除しています。またPSR-1[1]に従い、アンダースコア区切りではなく、camelBack記法に変更したので、addItem()
としています。
治療ポイント3. 配列の操作を修正
配列を格納する変数の初期化では、下記のように[]
を代入するようにしました。PHPDocにより、この変数に格納するのは配列であることが明示されていますが、正しい初期値を入れることで、そのことがよりわかりやすくなっています。
次に配列を順に参照する処理をwhile
文からforeach
文に変更しています。これで添字の抜けなどを考慮せずに、配列の全要素を参照することができます。
治療ポイント4. PHPセッションの利用
実は、今回の治療で最も大きな変更となったのが、この点です。
ショッピングカートに追加した商品情報(商品コード、個数)は、一時情報としてセッションに保持するのが一般的です。元のコードでは、セッション機能を自作しており[2]、セッションIDの生成から、Cookieへの埋め込み、セッション値のデータベースからの読み取り、書き込みなどが実装されています。セッション機能は機能面だけではなく、セキュリティ面についても配慮して実装する必要があり、これはなかなか骨の折れる作業です。
現在のPHP(PHP 4以降)では、標準でセッション機能があるので、こうした自作をする必要はまったくありません。そこで、PHPのセッション機能を使うように変更しました。
まず、セッションから商品情報を読み込む処理ですが、26行目から始まるコンストラクタでこの処理を行っています。$_SESSION
変数を参照して、商品情報が存在すれば、メンバ変数$items
に代入しています。$_SESSION
変数は、セッション情報を操作するスーパーグローバル変数で、セッションの値はすべてこの変数に格納されています。つまり、この変数を参照することでセッション情報を読むことができます。
次に、セッションへ商品情報を書き込む処理は、77行目のsave()
メソッドで行っています。単に$_SESSION
変数にメンバ変数$items
の値を代入しているだけです。これによりセッションへ商品情報が格納されます。save()
メソッドは、addItem()
やdeleteItem()
など商品情報を操作する各メソッドから呼び出されるので、商品情報の内容が変化した場合は都度セッションの内容も更新されるようになっています。
このようにPHP標準のセッション機能を利用すれば、$_SESSION
変数を操作するだけで簡単にセッションを扱うことができます。セッションID生成や、Cookieへの埋め込み、期限切れデータの削除(GC)など自分で実装するにはひと手間がかかる部分もPHPが面倒を見てくれます。PHPでセッションを使う場合は、標準のセッション機構を利用しましょう。
治療を終えて
今回は、PHP 3の時代に実装されたクラスについて診断を行いました。診断したCartクラスは、ショッピングカートというお馴染みの内容で仕様がイメージしやすいものでした。また、コードの書き方に問題点はありましたが、メソッドなどは、ある程度適切に分けられていたので、その点については理解しやすいコードでした。
治療後の修正コードですが、まだ改良の余地があります。より良いコードにすべく考えてみてください。
- セッション操作を行うクラスを作り、そのインスタンスを使ってセッション操作を行う
getTotalCount()
メソッドを、PHPの標準関数を使って1行で実装する
Acme\NotFoundException
クラスは別ファイルにする
今回はここまでです。また次回の診断でお会いしましょう。