修正コード
第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
クラスは別ファイルにする
今回はここまでです。また次回の診断でお会いしましょう。