新年あけましておめでとうございます。昨年暮れに始まった本連載ですが、
PHPにはPHPの書き方がある
2014年最初の患者さんは、
今回は、
<?php
/*=============================================================================
title : Cartクラス
commnets: 買い物カゴを定義する
コンストラクタで、一意のカートID&カートDBに新レコードを
生成。
カートIDはクッキーに発行し、セッション管理を行う
how to :
filename: cart.inc
date : 2000/06/22
===========================================================================*/
/*---------------------------------------------------------------------------*/
/* 定数定義
/*---------------------------------------------------------------------------*/
define("CART_ISSUE_TIME", 24); //カート有効時間
class Cart{
//メンバ変数
var $a_Item = ""; //アイテム情報
var $cCartId; //カートID
var $iMoney = 0; //合計金額
/*-----------------------------------------------------------------------*/
/* コンストラクタ
/*-----------------------------------------------------------------------*/
function Cart(){
global $CK_cCartId;
//カートIDセット
if(!$CK_cCartId) $CK_cCartId = make_unique_code("cart", "id", 8);
$this->cCartId = $CK_cCartId;
}
/*-----------------------------------------------------------------------*/
/* 商品を追加する
/*-----------------------------------------------------------------------*/
function do_add_item($cGoodsCode){
$a_Value[0] = $this->cCartId;
$a_Value[] = date("YmdHis", mktime(date("H") + CART_ISSUE_TIME, date("i"), date("s"), date("m"), date("d"), date("Y"))); //有効時間時間;
$a_Value[] = $cGoodsCode;
$a_Value[] = 1;
$db = new DB;
$db->do_insert("cart", "", $a_Value);
}
/*-----------------------------------------------------------------------*/
/* 商品個数を修正する
/*-----------------------------------------------------------------------*/
function do_change_item($cGoodsCode, $iGoodsNum){
$a_Value[0] = $iGoodsNum;
//一時削除
$this->do_delete_item($cGoodsCode);
$a_Value[0] = $this->cCartId;
$a_Value[] = make_date("YmdHis");
$a_Value[] = $cGoodsCode;
$a_Value[] = $iGoodsNum;
$db = new DB;
$db->do_insert("cart", "", $a_Value);
}
/*-----------------------------------------------------------------------*/
/* 商品を削除する
/*-----------------------------------------------------------------------*/
function do_delete_item($cGoodsCode){
if($cGoodsCode == -1) $cWhere = " WHERE id=\"" . $this->cCartId . "\"";
else $cWhere = " WHERE id=\"" . $this->cCartId . "\" AND gds_id=\"" . $cGoodsCode . "\"";
$db = new DB;
$db->do_delete("cart", $cWhere);
}
/*-----------------------------------------------------------------------*/
/* カートIDをクッキーに保存
/*-----------------------------------------------------------------------*/
function set_cookie(){
setcookie("CK_cCartId", $this->cCartId, time()+3600);
}
/*-----------------------------------------------------------------------*/
/* カートを削除
/*-----------------------------------------------------------------------*/
function delete_cart(){
//クッキーを削除
setcookie("CK_cCartId", $this->cCartId, time()-1);
//DBを削除
$db = new DB;
$db->do_delete("cart", " WHERE id=\"" . $this->cCartId . "\"");
}
/*-----------------------------------------------------------------------*/
/* メンバ変数参照
/*-----------------------------------------------------------------------*/
/*---------- カートID ---------*/
function get_id(){
return $this->cCartId;
}
/*---------- 商品情報 ---------*/
function get_item(){
return $this->a_Item;
}
/*---------- 合計個数 ---------*/
function get_count(){
$count = 0;
while($this->a_Item[$i]){
$count += $this->a_Item[$i];
}
return $count;
}
}
?>
診断
1. 文字エンコーディングがShift_JIS、改行コードがCRLF
このPHPコードは、
PHPコードをShift_
現在では、
もし携帯電話など一部の古いデバイス向けにShift_mb_
やmb_
を使って、
2. ファイル拡張子が.inc
このコードのファイル名は
意図はわからないことはないですが、addHandler
やSetHandler
でPHPコードとして実行されるように設定を行う必要があります。
また、
現在はこうしたPHPファイルの種別によって拡張子を変えるという慣習はなく、
3. これはPHP?
コードを見て目に付くのが、
PHPにはPHPDocというコメント形式が広く使われています。PHPDocはJavadocから派生したもので、
たとえば、do_
メソッドのコメントが次のように書かれています。
/*-----------------------------------------------------------------------*/
/* 商品を追加する
/*-----------------------------------------------------------------------*/
これをPHPDoc形式で書くと次のようになります。引数や戻り値についても記載があり、
/**
* 商品を追加する
*
* @param string $cGoodsCode
* @return void
*/
PHPDocを使う理由は、
華麗なアスキーアートによるコメントも味があるのですが、
4. 変数名がハンガリアン
次に気になるのは、
現在ではあまり見なくなったハンガリアン記法ですが、
おそらくハンガリアン記法を知らない人にとっては、$a_
変数の$items
や$itemList
などであれば、item
が複数入っているリストのようなものであることが簡単に認識できます。つまり、
ちなみに、$CK_
変数は、
5. global文
30行目のコンストラクタで登場するのが悪名高きglobal
文です。これを見たら思わず身構えてしまうPHPerの諸兄も多いかと思います。
ご存じない方に向けて解説すると、global
文はグローバル変数をローカルスコープ内から操作できるようにする命令です。下記の例では、$CK_
というグローバル変数を操作できるようにしています。つまり、$CK_
の参照も値の変更も可能になります。
function Cart(){
global $CK_cCartId;
//カートIDセット
if(!$CK_cCartId) $CK_cCartId = make_unique_code("cart", "id", 8);
$this->cCartId = $CK_cCartId;
}
グローバル変数の利用はできるだけ避けたほうがよいです。
その理由はいくつかあるのですが、
どうしてもグローバル変数を使わないと処理が書けない、$CK_
の値を引き渡すだけで用が済みます。これを実装した例が下記になります。$CK_
の値は、Cart
クラスを利用する側が生成しておき、
$cCartId
を引数にとる function Cart ($cCartId){
$this->cCartId = $cCartId;
}
$CK_cCartId
をコンストラクタに渡すif (!$CK_cCartId) {
$CK_cCartId = make_unique_code("cart", "id", 8);
}
$cart = new Cart($CK_cCartId); // コンストラクタに$cCartIdを渡す
ほかには、Cart
クラスのメンバ変数$cCartId
にだけ、Cart
クラスの外からカートIDを参照したい場合は、getCartId()
のようなゲッターメソッドで参照します。
global
文の利用は、global
文を利用しないといけない場面はほぼないといってよいでしょう。
6. 配列の操作
配列の操作においてもなかなか特徴があります。
まず、$a_
というメンバ変数を初期化しているのですが、$a_
変数は、
var $a_Item = "";
そのあとのコードを見ると配列として操作しているので、[]
を渡したほうがよいですprotected
を設定しています)。
protected $a_Item = [];
// PHP 5.3未満
protected $a_Item = array();
次に114行目では、$this->a_
の値を順に参照しています。PHP 3当時はforeach
文が存在しなかったので、null
やfalse
などの場合、while
文がその時点で終了してしまいます。
配列を順に参照していくのであれば、foreach
文を使うのがよいでしょう
foreach ($this->a_Item as $k => $v) {
(snip)
}
なお、while
文の個所で最低でも1回はNotice
エラーが出ます。なぜNotice
エラーが出るのかは考えてみてください
治療すべきポイントを洗い出したところで、