カート画面の実装(カートの削除)
次に、カート画面の各商品の[削除]リンクがクリックされた場合の処理です。生成されたHTMLを見ると分かるとおり、削除リンクは
<a href="cart.php?cmd=del&code=1004">削除</a>
のように記述されており、cart.phpに対してGETリクエストを送信しています。GETリクエストのcmd=delの部分は、削除ボタンがクリックされたことをPHPに通知するために用います。code=1004の部分はクリックされた商品コードです。
削除機能は、38行目以降の以下の部分で実装しています。
if( $_REQUEST["cmd"] == "del")
{
for( $i = 0 ; $i < count( $_SESSION["cart"] ); $i++ )
{
if( $_SESSION["cart"][$i]["item_code"] == $_REQUEST["code"] )
{
// unset 命令は、変数を破棄する。
unset( $_SESSION["cart"][$i] );
}
}
// 削除すると配列の番号が歯抜けになるため、以下の処理で配列の番号を整理し直す。
$_SESSION["cart"] = array_merge($_SESSION["cart"]);
}
forループでカート内の商品数だけループしながら、削除リンクがクリックされた商品の商品コードを探し当て、変数の内容を破棄するunset命令を使用し、削除しています。配列の数は、forループに記述されている次の部分で習得しています。
count( $_SESSION["cart"] )
count命令は、配列の要素数を数える命令で、
count( 配列名 )
と記述します。
if( $_SESSION["cart"][$i]["item_code"] == $_REQUEST["code"] )
と書かれたif文では、現在ループ中の商品の商品コードと削除リンクがクリックされた商品の商品コードが同じかどうかを判定しています。forループを繰り返す度に、変数$iが0から1つずつ、カウントアップしていきます。
例えば$_SESSION["cart"][0]["item_code"]と記述すれば、カートの1つ目の商品の商品コードが、$_SESSION["cart"][1]["item_code"]と記述すれば、カート内の2つ目の商品の商品コードが取得できます。forループの中にif文を書くことで、カート内のすべての商品の商品コードをチェックしています。
ここでforeachループではなく、forループを用いているのは、foreachループでは思惑どおりにプログラムが動作しないためです。foreachループを用いると、通常は次のようなプログラムになるはずです。
foreach( $_SESSION["cart"] as $cart )
{
if( $cart["item_code"] == $_REQUEST["code"] )
{
unset( $cart );
}
}
一見、こう記述した方がシンプルに見えるのですが、上記の例でunsetしている$cartは、カート内の商品の実体を示すものではないことに注意してください。unset( $cart )と記述しても、カート内の商品は削除されません。
C言語の経験がある方はforeachループで削除機能を実現するために、foreachループ内での参照渡しについて調べることがあるかもしれませんが、PHPのバージョンによっては正しく動作しない場合(PHP Bugs: #29992: foreach by reference corrupts the array参照)もあるため注意してください。
最後にunset命令で歯抜けになった配列の番号を整理する必要があります。削除前のカートの配列に0番、1番、2番、3番と番号がふられていたとして、2番の商品をunset命令で削除すると、配列の番号が0番、1番、3番になってしまうためです。これを行っているのが以下の箇所です。
$_SESSION["cart"] = array_merge($_SESSION["cart"]);
