#ECサイトでのカート機能の実装

ネットショッピングなどのECサイトでは決済前にカートに入れる機能が不可欠なので、その機能の実装方法についてメモを残します。
## 作りたいもの
- カートの中身を確認する画面
- 商品詳細画面で個数を入力し、カートに入れるボタンを押すとカートに追加される
- カート確認画面では各商品の商品名、商品画像、紹介文、個数、合計金額が表示され、下部ですべての商品の合計が表示される
- 購入ボタンをおすと決済画面に遷移する

## カートに商品を入れる機能
以下の`product_detail.php`では商品リストから選んだ商品の画像、商品名、紹介文、単価が表示されます。

```php
<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>商品詳細</title>
  <link rel="stylesheet" type="text/css" href="stylesheet.css">

</head>
  <body>
    <h1>商品詳細</h1>

<?php
session_start();
  $id=$_POST['id'];




    $hostname = "localhost";    //ホスト名
    $userid = "iimori";    //データベースユーザ名
    $passwd = "A8h3avau";    //接続パスワード
    $dbname = "ecdatabase";    //データベース名
    $con=mysqli_connect($hostname,$userid,$passwd,$dbname);   //db接続に必要な情報を変数に入れる

            // 接続状況をチェックします
    if (mysqli_connect_errno()) {
        die("データベースに接続できません:" . mysqli_connect_error() . "\n");
    }

    $error="";
    $con->set_charset('utf8');

      /* プリペアドステートメントを作成します */
      if ($stmt = mysqli_prepare($con, "SELECT productName,productImagePath,introduce,price FROM product WHERE id = ?")) {

          /* マーカにパラメータをバインドします */
          mysqli_stmt_bind_param($stmt, "s", $id);

          /* クエリを実行します */
          mysqli_stmt_execute($stmt);

          /* 結果変数をバインドします */
          mysqli_stmt_bind_result($stmt, $productName,$productImagePath,$introduce,$price);


          /* 値を取得します */
          mysqli_stmt_fetch($stmt);

          /* ステートメントを閉じます */
          mysqli_stmt_close($stmt);
      }

    // 接続を閉じます
    mysqli_close($con);

 ?>

 <script>
 /**
  * 確認ダイアログの返り値によりフォーム送信
 */
 function logoutChk () {
     /* 確認ダイアログ表示 */
     var flag = confirm ( "本当にログアウトしますか？\n\n");
     /* send_flg が TRUEなら送信、FALSEなら送信しない */
     return flag;
 }

 </script>
<!– 左サイドメニュー –>
<div class="leftmenu">
<div class="subinfo"> <?php echo "ようこそ、".$_SESSION['name']."さん！"?> </div>

<!– メニュー –>
<div class="subinfo">
  <form  action="cart.php" method="post">
    <input type="submit" name="toCart" value="カートの中身を確認する">

  </form>
  <form  action="login.php" method="post">
    <input type="submit" name="logout" value="ログアウト">
  </form>
</div>

</div>


<div class="center">
  <img src="<?=$productImagePath; ?>"><br>
  <p><?=$productName?></p>
  <p><?=$introduce?></p>
  <p>￥<?=$price?></p>


<form method='post' action='product_list.php'>
<select name='quantity'>
  <?php for($i=1; $i<=9; $i++){
    echo "<option value=".$i.">".$i."</option>";
  }?>


</select>個
<br>
  <input type='submit' name= "cartIn" value='カートに入れる' />
  <input type="hidden" name="id" value="<?=$id?>">
</form>
<br>
<form  action="product_list.php" method="post">
  <input type='submit' name="cancel" value='戻る' />
</form>
</div>
</body>
</html>

```
商品の個数を選んでカートに入れるボタンを押すと、その個数だけカートに入ります。
商品一覧の中から押された商品のidをPOSTしてそのidの商品名や画像パスなどをDBから読み出しています。

## カート画面
以下はカートに入れた商品と合計金額を表示する`cart.php`です。

```php
<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>カート</title>
  <link rel="stylesheet" type="text/css" href="stylesheet.css">

</head>
  <body>
    <h1>カートに入っている商品</h1>
    <?php
    $productName=array();
    $productImagePath=array();
    $introduce=array();
    $price=array();
    $total=0;
    session_start();
    if(!empty($_SESSION['cart'])){
      $count=count($_SESSION['cart']);
    }else{
      $count=0;
    }

        $hostname = "localhost";    //ホスト名
        $userid = "iimori";    //データベースユーザ名
        $passwd = "A8h3avau";    //接続パスワード
        $dbname = "ecdatabase";    //データベース名
        $con=mysqli_connect($hostname,$userid,$passwd,$dbname);   //db接続に必要な情報を変数に入れる

                // 接続状況をチェックします
        if (mysqli_connect_errno()) {
            die("データベースに接続できません:" . mysqli_connect_error() . "\n");
        }

        $con->set_charset('utf8');
  if($count!=0){
        for($i=0; $i<$count; $i++){
          /* プリペアドステートメントを作成します */
          if ($stmt = mysqli_prepare($con, "SELECT productName,productImagePath,introduce,price FROM product WHERE id = ?")) {

              /* マーカにパラメータをバインドします */
              mysqli_stmt_bind_param($stmt, "s", $_SESSION['cart'][$i]);

              /* クエリを実行します */
              mysqli_stmt_execute($stmt);

              /* 結果変数をバインドします */
              mysqli_stmt_bind_result($stmt, $productName[$i],$productImagePath[$i],$introduce[$i],$price[$i]);


              /* 値を取得します */
              mysqli_stmt_fetch($stmt);

              /* ステートメントを閉じます */
              mysqli_stmt_close($stmt);
          }
    }
  }
        // 接続を閉じます
        mysqli_close($con);

     ?>

<script>
/**
 * 確認ダイアログの返り値によりフォーム送信
*/
function logoutChk () {
    /* 確認ダイアログ表示 */
    var flag = confirm ( "本当にログアウトしますか？\n\n");
    /* send_flg が TRUEなら送信、FALSEなら送信しない */
    return flag;
}

</script>


<!– 左サイドメニュー –>
<div class="leftmenu">
<div class="subinfo"> <?php

          if(isset($_SESSION['name'])){
            echo "ようこそ、".$_SESSION['name']."さん！";
          }else{
            header('Location:login.php');
            exit;

          }
 ?>

 </div>

<!– メニュー –>
<div class="subinfo">
  <form  action="cart.php" method="post">
    <input type="submit" name="toCart" value="カートの中身を確認する">
  </form>
  <form  method="post" action="product_list.php" onsubmit="return logoutChk()">
    <input type="submit" name="logout" value="ログアウト">
  </form>
  <form  method="post" action="product_list.php" >
    <input type="submit" name="toList" value="商品一覧に戻る">
  </form>
</div>

</div>


<div class="center">

  <div class="container">

<table width="100%">
  <?php
  if($count==0){
    echo "カートに何も入っていません。";
  }else{
    for($j=0; $j<$count; $j++){
  ?>


    <div class="item">
      <tr>

    <td width="20%"><img src="<?=$productImagePath[$j]; ?>" width="160" height="100"></td>
    <td width="10%"><?php echo htmlspecialchars($productName[$j],ENT_QUOTES,'UTF-8');?></td>
    <td width="40%"><?php echo htmlspecialchars($introduce[$j],ENT_QUOTES,'UTF-8'); ?></td>
    <td width="10%"><?php echo $_SESSION['quantity'][$j]."個";?>
    <td width="20%"><?php echo "￥".$price[$j]*$_SESSION['quantity'][$j]; ?></td>

    </td>
    </tr>
    </div>




  <?php
    $total+=$_SESSION['quantity'][$j]*$price[$j];
    }

  }
  ?>
  </div>
  </table>
  <div class="total">
    合計金額: <?=$total?>
  </div>
</br>
  <input type="submit" name="purchase" value="購入する">
</div>

  </body>
</html>
```

カートに入っているものは$_SESSION['cart']を配列として定義してそこに商品のidが代入されています。
そしてfor文でその配列の要素の数だけ繰り返し、そのidと一致する商品の商品名、商品画像、紹介文、単価をDBから取り出し、それぞれ配列`$productName[]`,`$productImagePath[]`,`$introduce[]`,`$price[]`に代入されます。  
それとは別にセレクターで選んだ個数が`$_SESSION['quantity'][]`に代入され、それを用いて合計金額を表示しています。
購入するボタンを押すと決済画面に遷移します。