4992


失礼します。  
phpとmysqlを利用したショッピングカートシステムを作ろうとしています。  
現在、商品名を検索するとデータベースから参照して検索条件と一致する商品を一覧表示するところまではできました。  
次の取り組みとして、｢カートに入れる｣ボタンを押すとカートページに飛び、ボタンを押した商品のデータをセッションに保持させ、その情報を表示するという事を可能にしたいです。

自分でコードを組んでみたのですが、以下の問題点が出てきました。  
1.セッションに情報を保存できない問題  
2.配列の最後に格納されているデータしかPOSTで取得できない問題  
この2点になります。

1についてですが、正確にはセッションに情報を保存できているのかもしれませんが私の知識が足りないばかりに上手くセッションを使えていないため、質問させていただきたいです。  
これはつまり何が言いたいかというと、  
商品「りんご」をカートに入れる→カートページにはりんごが表示されている→商品の一覧ページに戻る→商品みかんを入れる→カートページには商品「りんご」と商品「みかん」の2つが表示される  
このようにしたいのですが、商品「みかん」を入れてカートページに飛び、一覧ページに戻って商品「もも」をカートに入れるとカートページには商品「もも」しか表示されないのが現状なので、これを商品「みかん」と商品「もも」の2つを表示させられるようにしたいです。

2についてですが、商品ID「1」のりんごの「カートに入れる」ボタンをクリックした時、商品一覧ページにりんごのみがある場合には問題ないのですが、商品ID「2」のみかんも一緒に一覧ページに表示されている場合、りんごの「カートに入れる」ボタンを押してもカートページにはみかんが表示されてしまいます。  
試してみたところ、どうやら配列の一番最後に格納されているもののみを表示しているようです。  
これを最後だけではなく全て表示させたいです。

それではコードです。

商品一覧ページ(一部抜粋。他に原因が考えられる場合は追ってコードを載せます。)

[code]

    <?php
                foreach ($result as $row){
    ?>
                <div>
                <input type="hidden" name="id" value="<?php print $row['id'] ?>">
                <input type="hidden" name="name" value="<?php print $row['name'] ?>">
                <input type="hidden" name="price" value="<?php print $row['price'] ?>">
                <?php print h($row['name']) ?>
                <?php print h($row['price']) ?>
                <select name="num">
                    <option value="1">1</option>
                    <option value="2">2</option>
                    <option value="3">3</option>
                </select>
                <input type="submit" value="カートへ入れる">
                </div>
    <?php
                }
    ?>
    
[/code]

カートページ

[code]

    <?php
    //  HTTPヘッダーで文字コードを指定
    header("Content-Type:text/html; charset=UTF-8");
    ?>
    <?php
    session_start();
    
    //item_resultからpostでid,name,priceが送られてきたかを確認
    //もっと綺麗なコードになるんじゃなかろうか・・・
    if(isset($_POST['id'])){
        if(isset($_POST['name'])){
            if(isset($_POST['price'])){
             //送られてきたデータを配列に格納
             $item = array('id' => $_POST['id'],'name' => $_POST['name'],'price' => $_POST['price']);
            }
        }
    }else{
        $msg = 'no item';   //何もカートに入れてませんよー
    }
    //配列の中身確認用
    print_r ($item);
    
    //セッション変数「cart」が未設定の場合は０を設定
    if(!isset($_SESSION['cart'])){
        $_SESSION['cart'] = 0;
    }
    
    //セッション変数「cart」に配列の中身を格納
    //セッションにカートに入れる商品の情報が登録したい(できてなかった)
    $_SESSION['cart'] = $item;
    
    
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
    <head>
    <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
    <meta http-equiv="content-script-type" content="text/javascript" />
    <meta http-equiv="content-style-type" content="text/css" />
    <!--  StyleSheet記述
    <link rel="stylesheet" href="./css/main.css" type="text/css" media="all" />
    StyleSheet記述  -->
    <!-- PAGE TITLE -->
    <title>ページタイトル</title>
    </head>
    <body>
    
    <h1>カートの中身</h1>
    
    <?php
    //セッション変数「cart」の中身を表示したい
    foreach ($_SESSION['cart'] as $val){
        print $val."<br />";
    }
    
    ?>
    <br />
    <br />
    <a href="item_result.php">戻る</a>
    </body>
    </html>
    
[/code]

よろしくお願いします。


CC BY-SA 3.0
2015-01-21T09:02:22.660
4990
2015-01-21T10:26:21.747
5985
question
php
セッションに情報を保存できない問題と、配列の最後に格納されているデータしかPOSTで取得できない問題。


> 1.セッションに情報を保存できない問題

こちらは、セッション自体は問題なく使えているようですが、以下コードに問題があると思います。

[code]

    //セッション変数「cart」に配列の中身を格納
    //セッションにカートに入れる商品の情報が登録したい(できてなかった)
    $_SESSION['cart'] = $item;
    
[/code]

これですと、商品が追加される毎に `$_SESSION['cart']` の値を `$item`
にしていますので、前のデータが消え、新しい値で上書きされてしまいます。

例えば、以下のように配列として `$item` をその要素として追加していくことが可能です。

[code]

    //セッション変数「cart」が未設定の場合は空の配列に初期化
    if(!isset($_SESSION['cart'])){
        $_SESSION['cart'] = array();
    }
    
    //セッション変数「cart」に配列の中身を追加
    $_SESSION['cart'][] = $item;
    
[/code]

なお、この手の問題で行き詰まった時は、変数の状態を確認してみると問題がどこで起きているのかを特定しやすいです。

今回の場合、例えば、以下のように `var_dump()`
を使ってセッションの状態を更新前と更新後で出力してみると、値が上書きされている事が分かったかと思います。

[code]

    echo "セッションの状態：\n";
    var_dump($_SESSION); // セッションの中身を表示
    
    //セッション変数「cart」に配列の中身を格納
    //セッションにカートに入れる商品の情報が登録したい(できてなかった)
    $_SESSION['cart'] = $item;
    
    echo "値更新後のセッションの状態：\n";
    var_dump($_SESSION); // セッションの中身を表示
    
[/code]

> 2.配列の最後に格納されているデータしかPOSTで取得できない問題

こちらについては `form` タグの問題ではないでしょうか？  
一つの form 内に同一nameの値（inputタグやselect、textareaタグなどで）が複数ある場合、最後の値のみがサーバーへ送られます。

以下の様に、1商品毎に form を生成するようにすればいいかと思います。

[code]

    <?php
            foreach ($result as $row){
    ?>
            <div>
                <form action="/path/to/cart.php" method="post">
                <input type="hidden" name="id" value="<?php print $row['id'] ?>">
                <input type="hidden" name="name" value="<?php print $row['name'] ?>">
    <!-- (省略) -->
                <input type="submit" value="カートへ入れる">
                </form>
            </div>
    <?php
            }
    ?>
    
[/code]


CC BY-SA 3.0
2015-01-21T09:38:53.343
4992
2015-01-21T10:14:57.467
2015-01-21T10:14:57.467
2944
2944
4990
answer


  1. セッションに情報を保存できない問題

セッションを毎回上書きしているので、  
`$_SESSION['cart']` に `[]` を追加すればいいかなと思います。

[code]     //セッション変数「cart」に配列の中身を格納

    //セッションにカートに入れる商品の情報が登録したい(できてなかった)
    $_SESSION['cart'][] = $item;
    
[/code]

  2. 配列の最後に格納されているデータしかPOSTで取得できない問題

`form` タグの記載がないので、おそらく html に 1 つしか `form` タグがないかもしれません。  
簡単に実装するのであれば、`form` タグを `foreach` の中に入れてあげるといけると思います。

[code]     <?php

                foreach ($result as $row){
    ?>
                <form action="" method="post">
                    <div>
                    <input type="hidden" name="id" value="<?php print $row['id'] ?>">
                    <input type="hidden" name="name" value="<?php print $row['name'] ?>">
                    <input type="hidden" name="price" value="<?php print $row['price'] ?>">
                    <?php print h($row['name']) ?>
                    <?php print h($row['price']) ?>
                    <select name="num">
                        <option value="1">1</option>
                        <option value="2">2</option>
                        <option value="3">3</option>
                    </select>
                    <input type="submit" value="カートへ入れる">
                    </div>
                </form>
    <?php
                }
    ?>
    
[/code]


CC BY-SA 3.0
2015-01-21T09:44:04.923
4993
2015-01-21T10:26:21.747
2015-01-21T10:26:21.747
4978
7639
4990
answer