修正コード
第3回目で診断したPHPコードについて、
修正コードのポイントですが、
では、
<?php
namespace Acme;
/**
* Cartクラス。買い物カゴを定義する。カート情報はセッションに保存する。
*
* @author Foo
*/
class Cart
{
/**
* セッションキー
*/
const SESSION_KEY = 'SESSION_CART';
/**
* アイテム情報
*
* @var array
*/
protected $items = [];
/**
* コンストラクタ
*/
public function __construct()
{
if (session_status() != PHP_SESSION_ACTIVE) {
session_start();
}
if (empty($_SESSION[static::SESSION_KEY])) {
$this->items = [];
} else {
$this->items = $_SESSION[static::SESSION_KEY];
}
}
/**
* 商品を追加する
*
* @param string $itemCode
* @param integer $itemCount
*/
public function addItem($itemCode, $itemCount)
{
if (empty($this->items[$itemCode])) {
$this->items[$itemCode] = $itemCount;
} else {
$this->items[$itemCode] += $itemCount;
}
$this->save();
}
/**
* 商品個数を修正する
*
* @param string $itemCode
* @param integer $itemCount
* @throws \Acme\NotFoundException
*/
public function changeItem($itemCode, $itemCount)
{
if (empty($this->items[$itemCode])) {
throw new NotFoundException();
}
if ($itemCount > 0) {
$this->items[$itemCode] = $itemCount;
} else {
unset($this->items[$itemCode]);
}
$this->save();
}
/**
* カートをセッションに保存
*/
protected function save()
{
$_SESSION[static::SESSION_KEY] = $this->items;
}
/**
* カートを削除する
*/
public function clear()
{
$this->items = [];
$this->save();
}
/**
* 商品を削除する
*
* @param string $itemCode
*/
public function deleteItem($itemCode)
{
unset($this->items[$itemCode]);
$this->save();
}
/**
* 商品情報を取得
*
* @return array
*/
public function getItems()
{
return $this->items;
}
/**
* 合計個数を取得
*
* @return integer
*/
public function getTotalCount()
{
$total = 0;
foreach($this->items as $v) {
$total += $v;
}
return $total;
}
}
/**
* NotFoundException
*/
class NotFoundException extends \Exception {}
治療ポイント1. コメントをPHPDocに変更
コメントを記号で彩られた元の形からPHPDocに変更しました。これによりグッと今っぽいPHPコードになったのではないでしょうか。コメントは動作には影響しないものですが、
PHPDoc形式で書かれたコメント部分をDocBlockと言います。下記がaddItem()メソッドのDocBlockとなります。DocBlockにある@paramタグはメソッドの引数を表しており、addItem()メソッドには、$itemCodeとinteger型の$countの2つの引数があることがわかります。また、@returnタグがないので、@return voidと表記する場合もあります)。
/**
* 商品を追加する
*
* @param string $itemCode
* @param integer $count
*/
public function addItem($itemCode, $count)
phpDocumentorというAPIリファレンスを自動生成するツールでこのPHPファイルのリファレンスを生成した例が下記です。
先ほどのaddItem()メソッドの個所を抜粋しています。DocBlockに記述したコメントやタグが見やすい形式で出力されています。このようにPHPDoc形式でコメントを書くことでこういったツール群の恩恵を受けることができます。
治療ポイント2. ハンガリアン記法からの脱却、メソッド名の見直し
変数名を修正して、$a_ はアイテムが複数であることを示すように$itemsへ、$cGoodsCodeは商品を示す単語をitemに統一して$itemCodeへ、$iGoodsNumも同様に$itemCountへ変更しています。
無駄なプレフィックスがなくなったことで、
メソッド名についても読みやすいように変更を行いました。いくつかのメソッドではdo_のように先頭にaddItem()としています。
治療ポイント3. 配列の操作を修正
配列を格納する変数の初期化では、[]を代入するようにしました。PHPDocにより、
protected $items = [];
次に配列を順に参照する処理をwhile文からforeach文に変更しています。これで添字の抜けなどを考慮せずに、
foreach($this->items as $v) {
$total += $v;
}
治療ポイント4. PHPセッションの利用
実は、
ショッピングカートに追加した商品情報
現在のPHP
まず、$_SESSION変数を参照して、$itemsに代入しています。$_SESSION変数は、
if (empty($_SESSION[static::SESSION_KEY])) {
$this->items = [];
} else {
$this->items = $_SESSION[static::SESSION_KEY];
}
次に、save()メソッドで行っています。単に$_SESSION変数にメンバ変数$itemsの値を代入しているだけです。これによりセッションへ商品情報が格納されます。save()メソッドは、addItem()やdeleteItem()など商品情報を操作する各メソッドから呼び出されるので、
$_SESSION[static::SESSION_KEY] = $this->items;
このようにPHP標準のセッション機能を利用すれば、$_SESSION変数を操作するだけで簡単にセッションを扱うことができます。セッションID生成や、
治療を終えて
今回は、
治療後の修正コードですが、
- セッション操作を行うクラスを作り、
そのインスタンスを使ってセッション操作を行う getTotalCount()メソッドを、PHPの標準関数を使って1行で実装する Acme\NotFoundExceptionクラスは別ファイルにする
今回はここまでです。また次回の診断でお会いしましょう。