php+mysqlのショッピングカートについて質問です


データベースのテーブル(item)

 品番   |カテゴリー | 商品名  |  金額  |  在庫  |
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
 item1  |  item2  |  item3  |  item4  |  item5  |
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
A001011 | デザイン |デザイン1 |  500  | 100   |
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
 mai1  |  枚数  | 100枚  |  1000 | 100   |
・・・

商品はすべて1つのテーブルに登録してあります。

htmlのフォームを使って
<select name="design" id="design">
<option value="A001011">A001011</option>
</select>
<select name="mai" id="mai">
<option value="mai1">100枚</option>
<option value="mai2">200枚</option>
</select>

cart.phpで
 品番   | 商品名  |  金額  |
ーーーーーーーーーーーーーーーーーー
 item1  | item3  |  item4  | 
ーーーーーーーーーーーーーーーーーー
・・・
       合計  |     |
と、表示させたいです。

ソースを書く流れと見本のソースがあったら教えて下さい。よろしくお願い致します。

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2010/06/22 20:00:57
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:koriki-kozou No.1

回答回数480ベストアンサー獲得回数79

ポイント100pt

(1)仮にフォームでdesignが5で、maiがmai2だった場合、データベースに問い合わせるには以下のようなSQLが必要

SELECT `品番`,`カテゴリー`,`商品名`,`金額`,`在庫`,`item1`,`item2`,`item3`,`item4`,`item5` FROM item
WHERE `品番` = 5 AND `mai` = 'mai2'

一行目は常に変わらないけど5や'mai2'は受け取ったパラメータを代入しなければならないから下記のような具合で代入

. " WHERE 品番=" . mysql_real_escape_string($_POST['design'])
. " AND mai='" . mysql_real_escape_string($_POST['mai']) . "'"

例では $sql という変数に一度代入してあるので、まずは $sql に思い通り(上記の)SQLになっているかを echoで出力して確認してみて


(2)補足

一行目はカラムを列挙せずに SELECT * FROM item で済ませてもいいけど、個人的には必要なカラムを列挙しておくことを奨める

(*は自動処理に任せるってことなので、バグになってしまう場合も稀にある。面倒でも明記してあればミスに気づきやすい)

バッククォートは特殊文字や予約語が混じっていたりした場合のためのもので、特殊文字も予約語も含んでいないとはっきりわかっている場合は無くてもいい

シングルクォートは文字列を扱う場合に使う

mysql_real_escape_string は送られてきたパラメータに特殊文字を混入された場合でも問題ないようにするための措置


(3)訂正

過去の回答 http://q.hatena.ne.jp/1274775856 では大きなミスがありました

$sql に SQL を生成しただけで、データベースに問い合わせるという行が抜けてました

お詫びして訂正します

$result = mysql_query($sql) or die 'システムエラー3';
$row = mysql_fetch_assoc($result) or die 'システムエラー4';
echo $row['価格'];

http://php.net/manual/ja/function.mysql-fetch-assoc.php

id:kasai-de_eb

有難うございます。

http://q.hatena.ne.jp/1274775856 について質問がしたいんですが、

require( '../config.php' );

// db connect

$link = mysql_connect( $db_host, $db_user, $db_password );

mysql_select_db( $db_name );

$result = mysql_query( 'set character set utf8' );


$sql = "SELECT * FROM item"

. " WHERE 種類 ='" . mysql_real_escape_string($_POST['desgin']) . "'"

. " AND 枚数 ='" . mysql_real_escape_string($_POST['mai']) . "'";

$result = mysql_fetch_assoc($link) or die 'システムエラー3';

$row = mysql_fetch_assoc($result) or die 'システムエラー4';

echo $row['価格'];

mysql_close($link);


?>

だと

$result = mysql_fetch_assoc($link) or die 'システムエラー3'; の文にエラーがでます。何か間違っていますでしょうか?

2010/06/19 18:02:00

その他の回答1件)

id:koriki-kozou No.1

回答回数480ベストアンサー獲得回数79ここでベストアンサー

ポイント100pt

(1)仮にフォームでdesignが5で、maiがmai2だった場合、データベースに問い合わせるには以下のようなSQLが必要

SELECT `品番`,`カテゴリー`,`商品名`,`金額`,`在庫`,`item1`,`item2`,`item3`,`item4`,`item5` FROM item
WHERE `品番` = 5 AND `mai` = 'mai2'

一行目は常に変わらないけど5や'mai2'は受け取ったパラメータを代入しなければならないから下記のような具合で代入

. " WHERE 品番=" . mysql_real_escape_string($_POST['design'])
. " AND mai='" . mysql_real_escape_string($_POST['mai']) . "'"

例では $sql という変数に一度代入してあるので、まずは $sql に思い通り(上記の)SQLになっているかを echoで出力して確認してみて


(2)補足

一行目はカラムを列挙せずに SELECT * FROM item で済ませてもいいけど、個人的には必要なカラムを列挙しておくことを奨める

(*は自動処理に任せるってことなので、バグになってしまう場合も稀にある。面倒でも明記してあればミスに気づきやすい)

バッククォートは特殊文字や予約語が混じっていたりした場合のためのもので、特殊文字も予約語も含んでいないとはっきりわかっている場合は無くてもいい

シングルクォートは文字列を扱う場合に使う

mysql_real_escape_string は送られてきたパラメータに特殊文字を混入された場合でも問題ないようにするための措置


(3)訂正

過去の回答 http://q.hatena.ne.jp/1274775856 では大きなミスがありました

$sql に SQL を生成しただけで、データベースに問い合わせるという行が抜けてました

お詫びして訂正します

$result = mysql_query($sql) or die 'システムエラー3';
$row = mysql_fetch_assoc($result) or die 'システムエラー4';
echo $row['価格'];

http://php.net/manual/ja/function.mysql-fetch-assoc.php

id:kasai-de_eb

有難うございます。

http://q.hatena.ne.jp/1274775856 について質問がしたいんですが、

require( '../config.php' );

// db connect

$link = mysql_connect( $db_host, $db_user, $db_password );

mysql_select_db( $db_name );

$result = mysql_query( 'set character set utf8' );


$sql = "SELECT * FROM item"

. " WHERE 種類 ='" . mysql_real_escape_string($_POST['desgin']) . "'"

. " AND 枚数 ='" . mysql_real_escape_string($_POST['mai']) . "'";

$result = mysql_fetch_assoc($link) or die 'システムエラー3';

$row = mysql_fetch_assoc($result) or die 'システムエラー4';

echo $row['価格'];

mysql_close($link);


?>

だと

$result = mysql_fetch_assoc($link) or die 'システムエラー3'; の文にエラーがでます。何か間違っていますでしょうか?

2010/06/19 18:02:00
id:doropon No.2

回答回数94ベストアンサー獲得回数16

ポイント28pt

$result = mysql_fetch_assoc($link) or die 'システムエラー3';

だと流れ的に

$result = mysql_query($sql) or die 'システムエラー3';

な気がします。




データベースサーバに接続

$link = mysql_connect( $db_host, $db_user, $db_password );

データベースに接続

mysql_select_db( $db_name );

utf-8を使う

$result = mysql_query( 'set character set utf8' );

sqlを組み立てて

$sql = "SELECT * FROM item"
. " WHERE 種類 ='" . mysql_real_escape_string($_POST['desgin']) . "'"
. " AND 枚数 ='" . mysql_real_escape_string($_POST['mai']) . "'";

sqlをなげる。

$result = mysql_fetch_assoc($link) or die 'システムエラー3';

が、いきなり結果をください。

に、なってしまっているので、

$result = mysql_query($sql) or die 'システムエラー3';

結果を取得

$row = mysql_fetch_assoc($result) or die 'システムエラー4';

で一連の流れができあがります。

id:kasai-de_eb

有難うございます。

$sql = "SELECT * FROM item"

. " WHERE 種類 ='" . mysql_real_escape_string($_POST['desgin']) . "'"

. " AND 枚数 ='" . mysql_real_escape_string($_POST['mai']) . "'";

の部分について何ですが、

上記のデータベースから呼び出すには

$sql = "SELECT * FROM item"

. " WHERE item1 ='" . mysql_real_escape_string($_POST['desgin']) . "'"

. " AND item1 ='" . mysql_real_escape_string($_POST['mai']) . "'";

であっているのでしょうか?

この辺りを説明してくれるサイト等知っていたら教えて下さい。

2010/06/22 15:54:04
  • id:koriki-kozou
    koriki-kozou 2010/06/19 16:25:16
    >ソースを書く流れと見本のソース
    http://q.hatena.ne.jp/1274775856
    ・入力する値としての種類や枚数 などを品番や枚数などに
    ・出力する値としての金額は、金額
    ・受け渡す変数としてのselectやselect1 などを designやmaiなど
    にそれぞれ置き換えてみるところまではやってみた?
  • id:koriki-kozou
    koriki-kozou 2010/06/19 16:33:49
    受け取ったデータをチェックしてからデータベースにデータを取りに行って出力する全体の流れはこっちね
    http://q.hatena.ne.jp/1275633015
    あわせると基本システムが出来上がるように回答してあるので、ちょっと読み直してみて
  • id:kasai-de_eb
    すみません。ご回答ありがとうございます。

    . " WHERE 種類='" . mysql_real_escape_string($_POST['select']) . "'"
    . " AND 版代='" . mysql_real_escape_string($_POST['select2']) . "'"
    . " AND 枚数=" . mysql_real_escape_string($_POST['select3']);

    の部分が理解出来ずにいます。

    種類や版代のところはには何を入れていいのかわかりませんでした。
    今回の内容で言うと種類や版代のところをどうかいたらいいのでしょうか?


  • id:koriki-kozou
    koriki-kozou 2010/06/19 18:33:35
    コピペミスしてるようですね
    (1)'システムエラー3'; の文にエラー
    $result = mysql_query($sql) or die 'システムエラー3';
    (2)item テーブルには「品番,カテゴリー,商品名,金額,在庫,item1,item2,item3,item4,item5」があって「種類,枚数」ってカラムは無いから、そこも変えて
    . " WHERE `品番`=" . mysql_real_escape_string($_POST['design'])
    . " AND `item1`='" . mysql_real_escape_string($_POST['mai']) . "'"
  • id:kasai-de_eb
    有難うございます。

    上のデータベースでいくと
    . " WHERE `item1`=" . mysql_real_escape_string($_POST['design'])
    . " AND `item1`='" . mysql_real_escape_string($_POST['mai']) . "'"

    であっているんでしょうか?

    今、持っている参考書にはデータベースからの呼び出しが全く書いていないため、
    内容が理解できていないんですが、
    説明がよっているページをご存知ではないでしょうか?
  • id:koriki-kozou
    koriki-kozou 2010/06/22 16:39:36
    MySQLを使うならばSQLについて理解しないといけないし、こちらの回答もしっかり読み直してほしい(残念ながら、部分部分飛ばし飛ばしに読み取ってるとしか思えない)
    どんな本を読んでるのか知らないけど、雑誌の一部特集記事などを参考にしているのであれば、それは初心者向けではないからやめておいたほうがいい
    カートシステムを作成するためには、ブラウザとWEBサーバーとのやりとりに関する部分から、phpなどのサーバーサイド処理(時にはクライアントサイド処理も含まれる)、ならびに、MySQLなどのバックエンド処理と多岐にわたる知識が必要となるため、未知の状態からカートシステム構築を目指そうとすれば1冊の分厚い本になっても足りない
    分厚ければいいというものでもないので、書店に足を運んで、自分の理解できそうな範囲で、別の本を探すことを奨めたいね


    さて、やりはじめたものを放棄するのももったいないので、再度整理してみたい
    下記が、回答1からコメント2010-06-19 18:33:35までの間に私が考えたこと。
    kasai-de_eb さんと認識が違っているところがあれば、そこが原因
    (1)itemテーブルには以下の十項目が存在するとする
    |品番|カテゴリー|商品名|金額|在庫|item1|item2|item3|item4|item5|

    (2)itemテーブルには以下のデータが入っているものとする
    |A001011|デザイン|デザイン1| 500|100|mai1|枚数|100枚|1000|100|
    |A001011|デザイン|デザイン1|1000|100|mai2|枚数|200枚|2000|200| ←以降、こちらを抜き出すことを目標とする

    (3)データを抜き出すSQLは以下のようになる
    $sql = "SELECT `品番`,`カテゴリー`,`商品名`,`金額`,`在庫`,`item1`,`item2`,`item3`,`item4`,`item5` FROM item"
    . "WHERE `品番` = 'A001011' AND `item1` = 'mai2'";

    (4)A001011 と mai2 についてはフォームから送られてくるものを使うので以下のようになる
    $sql = "SELECT `品番`,`カテゴリー`,`商品名`,`金額`,`在庫`,`item1`,`item2`,`item3`,`item4`,`item5` FROM item"
    . " WHERE `品番`='" . mysql_real_escape_string($_POST['design']) . "'"
    . " AND `item1`='" . mysql_real_escape_string($_POST['mai']) . "'";
  • id:kasai-de_eb
    有難うございます。
    また、書いて頂いたところをよんでいるところですが、
    データベースの
    フィールド名が item1・item2・item3・item4・item5 となっていて

    item1には品番が収納されていて A001011とmai1です。

    item2にはカテゴリーが収納されていて デザインと枚数です。

     品番   |カテゴリー | 商品名  |  金額  |  在庫  |
    ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
     item1  |  item2  |  item3  |  item4  |  item5  |
    ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
    A001011 | デザイン |デザイン1 |  500  | 100   |
    ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
     mai1  |  枚数  | 100枚  |  1000 | 100   |

    わかりにくくてすみません。
    また読んでいる途中なんですが、私の書き方が悪かったみたいで、
    すみません。
  • id:kasai-de_eb
    koriki-kozou 様

    いつもご丁寧に有難うございます。
    <select name="design" id="design">
    <option value="A001011">A001011</option>
    </select>
    <select name="mai" id="mai">
    <option value="mai1">100枚</option>
    <option value="mai2">200枚</option>
    </select>

    で送ったないようを

    $sql = "select * from item WHERE item1 = '" . mysql_real_escape_string($_POST['desgin']) . "'" ;

    で「A001011 | デザイン |デザイン1 |  500  | 100   」を内容を呼び出すことは出来ました。

    有難うございました。

    ただ、ANDをつけた文にすると「A001011 | デザイン |デザイン1 |  500  | 100  」は反映されません。

    度々すみません。せっかく書いて頂いた文を理解できていない様なのでご指摘の通り何度も読み直してみます。
  • id:koriki-kozou
    koriki-kozou 2010/06/22 17:52:17
    書き方ではなくて考え方がそもそも違っている点が原因ですね
    (a)Excelのような表計算ソフト
    ・1つのセルに複数の情報を持たせることもあります
    (b)MySQLのようなデータベース
    ・1つのフィールドには1つの情報を入れるもの
    1つのフィールドに複数の情報(A001011とmai1がitem1に入っていたり、デザインと枚数がitem2に入っていたり)を入れるものではない
    ・1レコードに情報を集約します(複数レコードに分散する場合は、それぞれの関連性を示す項目が別途必要になります)
    以上のような理由で2010-06-22 16:39:36の(1)のように十項目と読み取りました


    結論としては設計自体を見直すべきですが、とりあえずの例として
    (5)A001011mai1 という形でitem1フィールドに入っているのだとすれば
    $sql = "SELECT `品番`,`カテゴリー`,`商品名`,`金額`,`在庫`,`item1`,`item2`,`item3`,`item4`,`item5` FROM item"
    . " WHERE `item1`='" . mysql_real_escape_string($_POST['design']) . mysql_real_escape_string($_POST['mai']) . "'";
    (6)item1フィールドにA001011と入っているレコードとitem1フィールドにmai1と入っているレコードが存在する場合
    $sql = "SELECT `品番`,`カテゴリー`,`商品名`,`金額`,`在庫`,`item1`,`item2`,`item3`,`item4`,`item5` FROM item"
    . " WHERE `item1`='" . mysql_real_escape_string($_POST['design']) . "'"
    . " OR `item1`='" . mysql_real_escape_string($_POST['mai']) . "'";

    上記(5)はケースバイケースで使う場合も稀にあるけれど、改変時に出くわしたらウザイ事この上ない。やめたほうがいい
    上記(6)は各レコードの関係をしめすフィールドが無いため、誤った情報を抜き出してくる可能性が非常に高く、このようなデータベース設計をやってはいけない

    全てitemで始まるフィールド名になっているが、プログラムミスを起こしやすく、また、発見も難しくなるため、それぞれ中身を理解しやすい名前を付けるほうがいい
    |no|category|name|price|stock|・・・
  • id:doropon
    $sql = "SELECT * FROM item"
    . " WHERE item1 ='" . mysql_real_escape_string($_POST['desgin']) . "'"
    . " AND item1 ='" . mysql_real_escape_string($_POST['mai']) . "'";

    うーん、item1で2つ絞るのは無いかと。

    フィールド名がitem1,item2となるとすると、
    品番ってどこから出てきましたでしょうか。
    A001011が品番っぽいのはわかるのですが、mai1がなんであるかが良く分からなくなりました。

    私の頭をまず落ちつけてと思いますが、
    テーブルの構造をはっきりさせないとわからないですね。

    mysqlだとすると、

    コマンドラインで、
    mysql
    use item
    show fields from item;
    select * from item;
    とするとテーブルの定義と内容をみることができます。
    phpmyadminでも定義やデータはみることができます。

    mysqlの使い方というよりはDBの基本的なところが必要かもしれないですね。

    どの本がお勧めってのは無いので難しいのですが、
    大抵の場合、市販されている本の内容はすべてを網羅できるものではないので、
    似通ったものでも数冊は並行してみてほしいとは思います。

    思うに、まずテーブルの構造ですね。
    で、中のデータ。
  • id:koriki-kozou
    koriki-kozou 2010/06/22 18:09:49
    doropon さん
    タイミングの問題かもしれないけどテーブルの構造については 17:25:50 のコメントで返事もらってるよ
    その前後の私とkasai-de_ebのコメントも読み直してみて、あなたの疑問点はすべて載ってるはずだから

    回答2もコメント欄で私が前日に答えてるし、回答1の(3)で示した過去のkasai-de_ebさんとのやりとりからの繋がりも読み直してもらえれば、さらに疑問は解消に向かうと思いますよ
  • id:kasai-de_eb
    未熟なものでどう説明をしたらいいのかわかりませんが、

    各フィールどには1つの情報しか収納していません。

    ※説明しやすい様にID(auto_increment)をつけます。

    項目は5項目です。
    フィールド名 item1・item2・item3・item4・item5 に各商品の詳細を収納。

    商品の内容が下記のようなない様です。

    ID:1
    item1:A001011
    item2:デザイン
    item3:デザイン1
    item4:500(円)
    item5:100(個)


    ID:2
    item1:mai1
    item2:枚数
    item3:100枚
    item4:1,000(円)
    item5:100(個)

    ID:3
    item1:A001012
    item2:デザイン
    item3:デザイン2
    item4:500(円)
    item5:100(個)


    といったかんじです。

    このやり方が違うということならすみません。
  • id:koriki-kozou
    koriki-kozou 2010/06/22 18:55:48
    何度もミスってごめん。

    2010-06-22 17:52:17の(6)が2010-06-22 18:21:28のような構造を想定してのSQLですが、テーブル構造としては破綻していると言わざるを得ないので、データが増えないうちに2010- 06-22 16:39:36(1)のように十項目が並ぶような構造への変更が必要

    横に並べるのは同じものを何度も登録する(A001011を何行も書く)ことになって効率悪いという場合は、テーブルの正規化(データベース用語、データを効率良く扱うためのテーブル構造を考えること)というものを行って、テーブルを複数に分けるというものがある
    テーブルitem には
    |ID|no|category|name|price|stock|
    |1|A001011|デザイン|デザイン1|500|100|
    |3|A001012|デザイン|デザイン2|500|100|
    テーブルitem2 には
    |ID|type|unit|sheets|price|stock|
    |1|mai1|枚数|100|1000|100|
    |1|mai2|枚数|200|2000|50|
    |3|mai1|枚数|10|100|1000|
    item と item2 はIDでつながりを示している

    この場合のSQL生成は下記のような具合
    (7)
    $sql = "SELECT `no`,`category`,`name`,`price`,`stock`,`type`,`unit`,`sheets`,`price`,`stock` FROM item"
    . " LEFT JOIN item2 USING(ID)"
    . " WHERE `no`='" . mysql_real_escape_string($_POST['design']) . "'"
    . " AND `type`='" . mysql_real_escape_string($_POST['mai']) . "'";
  • id:doropon
    ああ、そうですね。すいません。
    同じテーブルの中に系統が違うものがあるというところを勘違いしてました。


  • id:kasai-de_eb
    有難うございます。

    テーブルを作り直してみます。

    本当にいろいろとありがとうございました。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません