PHPのセッションでショッピングカート機能を自作する方法【完全ガイド】

ECサイトの心臓部とも言える「ショッピングカート」機能は、PHPのセッション管理を学ぶ上で最高の題材の一つです。ユーザーがサイト内を回遊しても、選んだ商品情報をサーバーに一時的に保持し続ける仕組みは、まさにセッションの得意分野です。

今回は、複数のPHPファイルを連携させ、基本的ながらも本格的なショッピングカートアプリケーションをゼロから構築する方法を、ステップバイステップで解説します。

【作成するファイル構成】

  1. shop.php: 商品一覧ページ。ここから商品をカートに追加します。
  2. cart.php: カートの中身を表示するページ。数量の変更や商品の削除ができます。
  3. clear_cart.php: カートの中身をすべて空にするためのスクリプトです。

目次

1. 商品データの準備とセッションの設計

まず、アプリケーション全体で利用する商品データを定義します。通常はデータベースから取得しますが、今回はPHPの連想配列で商品カタログ(マスタデータ)を作成します。この配列はshop.phpcart.phpの両方で利用します。

<?php // shop.php や cart.php の冒頭で定義
$products = [
    'desk_01' => ['name' => '快適ワークデスク', 'price' => 50000],
    'chair_07' => ['name' => '人間工学チェア', 'price' => 35000],
    'monitor_24' => ['name' => '24インチ4Kモニター', 'price' => 40000],
];

カートの中身は、セッションに$_SESSION['cart']という名前で保存します。その中身は**「商品ID」をキー、「数量」を値**とする、以下のようなシンプルな連想配列で管理します。 ['desk_01' => 2, 'chair_07' => 1]


2. shop.php – 商品一覧とカート追加機能

このページは、商品カタログを表示し、ユーザーが商品を選んでカートに入れるための入り口です。

shop.phpの主な処理】

  1. 必ずsession_start()でセッションを開始します。
  2. POSTリクエストがあれば、「カートに入れる」ボタンが押されたと判断し、$_SESSION['cart']に商品IDと数量を追加します。
  3. 商品カタログの配列をforeachでループさせ、全商品を表示します。
  4. 各商品のフォームには、商品IDをhiddenフィールドで含めておきます。

shop.php 完成コード】

<?php
session_start();

// 商品マスタ
$products = [
    'desk_01' => ['name' => '快適ワークデスク', 'price' => 50000],
    'chair_07' => ['name' => '人間工学チェア', 'price' => 35000],
    'monitor_24' => ['name' => '24インチ4Kモニター', 'price' => 40000],
];

// POSTリクエスト処理(カート追加)
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['product_id'])) {
    $product_id = $_POST['product_id'];
    $quantity = (int)($_POST['quantity'] ?? 1);

    if (isset($products[$product_id]) && $quantity > 0) {
        $_SESSION['cart'][$product_id] = $quantity;
    }
}

// 現在のカートの中身を取得
$cart = $_SESSION['cart'] ?? [];
?>
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>商品一覧</title>
</head>
<body>
    <h1>商品一覧</h1>
    <p><a href="cart.php">カートを見る (<?php echo count($cart); ?>件)</a></p>
    <table border="1" style="width:100%; text-align:center;">
        <thead><tr><th>商品名</th><th>価格</th><th>数量</th><th></th></tr></thead>
        <tbody>
            <?php foreach ($products as $id => $product): ?>
                <tr>
                    <form action="" method="POST">
                        <td><?php echo htmlspecialchars($product['name']); ?></td>
                        <td><?php echo number_format($product['price']); ?>円</td>
                        <td>
                            <select name="quantity">
                                <?php for ($i = 1; $i <= 10; $i++): ?>
                                    <option value="<?php echo $i; ?>"><?php echo $i; ?></option>
                                <?php endfor; ?>
                            </select>
                        </td>
                        <td>
                            <input type="hidden" name="product_id" value="<?php echo $id; ?>">
                            <?php if (isset($cart[$id])): ?>
                                <p style="color:green;">追加済み</p>
                            <?php else: ?>
                                <input type="submit" value="カートに入れる">
                            <?php endif; ?>
                        </td>
                    </form>
                </tr>
            <?php endforeach; ?>
        </tbody>
    </table>
</body>
</html>

3. cart.php – カートの中身と操作

カートの中身を一覧表示し、数量の変更や特定の商品の削除を行います。ここでもロジックを先に処理し、その後でHTMLを描画します。

cart.phpの主な処理】

  1. session_start()でセッションを開始します。
  2. POSTリクエストがあれば、kind(操作の種類)に応じて「数量変更」または「削除」を実行します。
  3. 処理後はheader()で自分自身にリダイレクトし、ブラウザの再読み込みによる意図しない再送信(二重送信)を防ぎます(PRGパターン)。
  4. 現在のカート情報と商品マスタを使って、商品名、価格、小計、合計金額を計算して表示します。

cart.php 完成コード】

<?php
session_start();

// 商品マスタ
$products = [
    'desk_01' => ['name' => '快適ワークデスク', 'price' => 50000],
    'chair_07' => ['name' => '人間工学チェア', 'price' => 35000],
    'monitor_24' => ['name' => '24インチ4Kモニター', 'price' => 40000],
];

// POSTリクエスト処理(数量変更・削除)
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['product_id'])) {
    $product_id = $_POST['product_id'];
    $kind = $_POST['kind'] ?? '';

    if ($kind === 'change') {
        $quantity = (int)($_POST['quantity'] ?? 1);
        if ($quantity > 0 && $quantity <= 10) {
            $_SESSION['cart'][$product_id] = $quantity;
        }
    } elseif ($kind === 'delete') {
        unset($_SESSION['cart'][$product_id]);
    }
    // PRGパターン: 処理後にリダイレクト
    header('Location: cart.php');
    exit;
}

$cart = $_SESSION['cart'] ?? [];
$total_price = 0;
?>
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>カートの中身</title>
</head>
<body>
    <h1>カートの中身</h1>
    <p><a href="shop.php">商品一覧へ戻る</a></p>

    <?php if (empty($cart)): ?>
        <p>カートは空です。</p>
    <?php else: ?>
        <table border="1" style="width:100%; text-align:center;">
            <thead><tr><th>商品名</th><th>価格</th><th>数量</th><th>小計</th><th></th></tr></thead>
            <tbody>
                <?php foreach ($cart as $id => $quantity): ?>
                    <?php
                        $product = $products[$id];
                        $subtotal = $product['price'] * $quantity;
                        $total_price += $subtotal;
                    ?>
                    <tr>
                        <td><?php echo htmlspecialchars($product['name']); ?></td>
                        <td><?php echo number_format($product['price']); ?>円</td>
                        <td>
                            <form action="" method="POST">
                                <select name="quantity">
                                    <?php for ($i = 1; $i <= 10; $i++): ?>
                                        <option value="<?php echo $i; ?>" <?php if($i === $quantity) echo 'selected'; ?>><?php echo $i; ?></option>
                                    <?php endfor; ?>
                                </select>
                                <input type="hidden" name="product_id" value="<?php echo $id; ?>">
                                <input type="hidden" name="kind" value="change">
                                <input type="submit" value="変更">
                            </form>
                        </td>
                        <td><?php echo number_format($subtotal); ?>円</td>
                        <td>
                            <form action="" method="POST">
                                <input type="hidden" name="product_id" value="<?php echo $id; ?>">
                                <input type="hidden" name="kind" value="delete">
                                <input type="submit" value="削除">
                            </form>
                        </td>
                    </tr>
                <?php endforeach; ?>
            </tbody>
        </table>
        <h2>合計金額: <?php echo number_format($total_price); ?>円</h2>
        <p><a href="clear_cart.php">カートを空にする</a></p>
    <?php endif; ?>
</body>
</html>

4. clear_cart.php – カートを空にする

このスクリプトは、カートのセッション情報をすべて削除し、cart.phpに戻すだけのシンプルな役割です。

clear_cart.php 完成コード】

<?php
session_start();

// カートのセッションを破棄
unset($_SESSION['cart']);

// カートページにリダイレクト
header('Location: cart.php');
exit;

まとめ

今回は、PHPのセッション機能をフル活用して、実践的なショッピングカートアプリケーションを構築しました。

【このプロジェクトの重要ポイント】

  1. セッションは、ユーザーごとの一時的なデータ(カート情報など)を保持するのに最適。
  2. 商品マスタなどの共通データは配列で定義し、各ページでIDをキーにして情報を参照する。
  3. 1つのページで複数の操作(数量変更、削除など)を行うには、hiddenフィールドで操作の種類を送信する。
  4. POST処理の後は**リダイレクト(PRGパターン)**を行い、意図しない二重送信を防ぐ。

この3つのファイルを連携させるアプリケーションの構造は、より複雑なWeb開発の基礎となります。ぜひこのコードをベースに、機能拡張に挑戦してみてください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次