SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

プログラミング未経験から始めるPHP入門

プログラムをブラッシュアップするテクニックを学ぼう!
プログラミング未経験から始めるPHP入門~応用編(9)

第16回

  • X ポスト
  • このエントリーをはてなブックマークに追加

プログラムのブラッシュアップ(関数を使ったカート画面の実装)

 それでは、関数を使用してcart.phpを書き換えてみます。サンプルソースのoriginalフォルダにあるcart.phpをメモ帳などで開き、87行目~96行目を削除し、次のように置き換えてください。

// d_purchase テーブルへの挿入
create_purchase( $mdb2, $customer_code, $total_price );

 また、その直後のforeachループを以下に置き換えます。

foreach( $_SESSION["cart"] as $cart )
{
	create_purchase_detail( 
		$mdb2, $order_id, $cart["item_code"], $cart["price"], $cart["num"] );
}

 最後に、4行目以降に次のコードを挿入します。

/**
 * d_purchase テーブルに挿入する関数
 */
function create_purchase( $mdb2, $customer_code, $total_price )
{
	// d_purchase テーブルへの挿入
	$sql = " insert into d_purchase( customer_code, purchase_date, total_price) ";
	$sql.= " values( ?, now(), ? ) ";
	$stmt = $mdb2->prepare( $sql );
	$res = $stmt->execute(
		array(
			$customer_code,
			$total_price
		)
	);
}

/**
 * d_purchase_detail テーブルに挿入する関数
 */
function create_purchase_detail( $mdb2, $order_id, $item_code, $price, $num )
{
	$sql = " insert into d_purchase_detail( order_id, item_code, price, num ) ";
	$sql.= " values( ?, ?, ?, ? ) " ;
	$stmt = $mdb2->prepare( $sql );
	$res = $stmt->execute(
		array(
			$order_id,
			$item_code,
			$price,
			$num
		)
	);
}

 編集が終了したら、C:\xampp\ec\cart.phpに上書き保存し、これまで同様に注文完了ができることを確認します。もし、うまく動作しない場合は、サンプルソースのSTEP1_Funcフォルダに完成版のファイルがあるので、そちらを利用してください。

 それでは、プログラムの解説です。今回作成した関数は、create_purchase関数とcreate_purchase_detail関数です。create_purchase関数は、d_purchaseテーブルにレコードを追加する関数です。create_purchase_detail関数は、d_purchase_detailテーブルにレコードを追加する関数です。create_purchase_detail関数に関しては、次のようにforeachループごと関数内で処理することもできなくはありません。

function create_purchase_detail( $mdb2, $order_id )
{
	foreach( $_SESSION["cart"] as $cart )
	{
		$sql = " insert into d_purchase_detail( order_id, item_code, price, num ) ";
		$sql.= " values( ?, ?, ?, ? ) " ;
		$stmt = $mdb2->prepare( $sql );
		$res = $stmt->execute(
			array(
				$order_id,
				$cart["item_code"],
				$cart["price"],
				$cart["num"]
			)
		);
	}
}

 しかし、上記の記述ではショッピングカートのセッション変数が存在しなければループできません。今回のECサイトでは、カート画面からしか呼び出されない関数のためこれでもいいのですが、将来的な機能追加を想定し、他の画面でも使いやすい関数にするためにループ処理は含めませんでした。関数のメリットの1つである「同じ処理を2度も3度も書く必要がなくなる」点を生かすために、将来も想定した「汎用性」の高い関数を記述するように心がけましょう。

プログラムのブラッシュアップ(トランザクションの理解)

 次に、データベース処理をより安全に行うための「トランザクション管理」という概念に関して説明をします。今回の注文確定処理のデータベース処理を考えてみましょう。次のような手順になるはずです。

  1. まず、d_purchaseに注文情報のサマリー(誰が、いつ、いくら買ったか)をINSERT
  2. 次に、買い物履歴詳細テーブルに、商品の個数分、購入した商品の決済時の金額をINSERT

 上記の手順では、SQLを何回実行することになるでしょうか? 仮に商品個数が4個あったとしたら、(1)のSQLを1回、(2)のSQLを4回、合計5回のSQLを発行することになります。順調に5回とも成功すれば問題はないのですが、もし、何らかの原因で、(2)のSQLの3回目で失敗したらどうなるでしょうか? 中途半端な決済情報がデータベースに残ってしまいます。

 このような場合は『すべて成功、またはすべて失敗』となるようにすることで中途半端な状態のデータを許可しないようにします。この考え方を「トランザクション管理」と呼びます。トランザクション管理が必要なのは、主に新規登録、更新、削除など「更新系SQL」と呼ばれる処理で、SELECT文のみの場合は特に必要ありません。トランザクションは次のSQLで管理します。

  1. begin:トランザクション開始
  2. commitbeginから成功したすべてのSQLをデータベースに反映する
  3. rollbackbeginから実行したすべてのSQLを破棄し、データベースに反映しない

 MDB2ではそれぞれ$mdb2->beginTransaction()$mdb2->commit()$mdb2->rollback()という命令があらかじめ用意されているので、今回はこれらの命令を用いてトランザクション管理を行います。

 トランザクション開始から、commitまたはrollbackの期間を「トランザクション内」と呼び、MDB2では$mdb2->inTransaction()という命令とif文を組み合わせることでトランザクション内か否かを判断できます。

次のページ
プログラムのブラッシュアップ(トランザクションの実装)

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
プログラミング未経験から始めるPHP入門連載記事一覧

もっと読む

この記事の著者

大家 正登(オオイエ マサト)

デジタルハリウッド『PHP 講座』講師。学生時代、スペイン語を専攻していたものの何故かプログラム言語に心が傾き、近所のフリープログラマーに弟子入り修行。その後中堅 SIer に 3 年間所属し、現在はフリーエンジニア。仕事の傍らジャズを演奏し、コントラバス 2 台と同居中。(ITエンジニア・大家正登のWeb...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/4792 2010/01/19 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング