phpの機能を使って自動見積りを作りたいです。

商品の詳細や金額はデータベーズに登録してあります。

見積りフォーム自体はプルダウンメニューを使って条件をお客さんに選んでいける様にしたいです。
<table>
種類<select name="select"><option>T100</option></select>
名入れ版代<select name="select2"><option>10cm角</option>
<option>20cm角</option></select>
枚数<select name="select3"><option>1</option><option>2</option></select>

枚数の部分が1枚が2枚になると2倍の金額ではなく1.8倍の金額になる為、
データベースには1枚の金額、2枚の金額それぞれを登録しました。
名入れサイズの部分の10cm角と20cm角の金額もそれぞれことなります。
データベースには下記のような情報が含まれています。
10cm角=3,000円
20cm角=5,000円
1枚=1,000円
2枚=1,800円
種類には金額が含まれていません。

見積りフォームには
種類+名入れサイズ+枚数=¥
となる様にしたいです。

情報が足りないかもしれませんが、
出来上りは「http://www.uphillprint.com/meishi_online.html」の様にしたいです。
ソースを書く流れと見本のソースがあったら教えて下さい。
よろしくお願い致します。

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

ベストアンサー

id:koriki-kozou No.1

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

ポイント39pt

確かにデータベースやテーブル構造がわかったほうが回答を絞りやすいので書いておくほうがいいね

phpということからデータベースはMySQLとして、テーブルは種類(text)、版代(text)、価格1(INT)、価格2(INT)というカラムを持つものと仮定して話を進める

phpからデータベースを扱うことは実に簡単で、下記のようなものを結果表示したい部分に組み込めばいい。

<?php
$con = mysql_connect(接続) or die 'システムエラー1';
mysql_select_db(データベース名) or die 'システムエラー2';
$sql = "SELECT * FROM テーブル名"
     . " WHERE 種類='" . mysql_real_escape_string($_POST['select']) . "'"
     . " AND 版代='" . mysql_real_escape_string($_POST['select2']) . "'";
$res = mysql_fetch_assoc($con) or die 'システムエラー3';
if ($_POST['select3'] == 1) {
    echo $res['価格1'];
} else {
    echo $res['価格2'];
}
mysql_close($con);
?>

・select/select1/select2では紛らわしくて記入ミスも起こしやすいし、プログラムを見直す際にもミスを起こしやすい

syurui/handai/maisuなどとでもしておいたほうが間違いを防げる

・上記のように、データベースの構造として横にデータを持つのは本来は効率が悪い

テーブルの構造を種類(text)、版代(text)、枚数(INT)、価格(INT)としておけば枚数割引が商品によって異なる場合などでも対応できるようになる

<?php
$con = mysql_connect(接続) or die 'システムエラー1';
mysql_select_db(データベース名) or die 'システムエラー2';
$sql = "SELECT * FROM テーブル名"
     . " WHERE 種類='" . mysql_real_escape_string($_POST['select']) . "'"
     . " AND 版代='" . mysql_real_escape_string($_POST['select2']) . "'"
     . " AND 枚数=" . mysql_real_escape_string($_POST['select3']);
$res = mysql_fetch_assoc($con) or die 'システムエラー3';
echo $res['価格'];
mysql_close($con);
?>

さらに効率をあげたい場合は・・・ケースバイケースなので、ひとまずこの辺で

id:kasai-de_eb

分かりやすご回答をいただき有難うございました。

とっても参考になりました。

2010/05/26 15:42:37

その他の回答3件)

id:koriki-kozou No.1

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

ポイント39pt

確かにデータベースやテーブル構造がわかったほうが回答を絞りやすいので書いておくほうがいいね

phpということからデータベースはMySQLとして、テーブルは種類(text)、版代(text)、価格1(INT)、価格2(INT)というカラムを持つものと仮定して話を進める

phpからデータベースを扱うことは実に簡単で、下記のようなものを結果表示したい部分に組み込めばいい。

<?php
$con = mysql_connect(接続) or die 'システムエラー1';
mysql_select_db(データベース名) or die 'システムエラー2';
$sql = "SELECT * FROM テーブル名"
     . " WHERE 種類='" . mysql_real_escape_string($_POST['select']) . "'"
     . " AND 版代='" . mysql_real_escape_string($_POST['select2']) . "'";
$res = mysql_fetch_assoc($con) or die 'システムエラー3';
if ($_POST['select3'] == 1) {
    echo $res['価格1'];
} else {
    echo $res['価格2'];
}
mysql_close($con);
?>

・select/select1/select2では紛らわしくて記入ミスも起こしやすいし、プログラムを見直す際にもミスを起こしやすい

syurui/handai/maisuなどとでもしておいたほうが間違いを防げる

・上記のように、データベースの構造として横にデータを持つのは本来は効率が悪い

テーブルの構造を種類(text)、版代(text)、枚数(INT)、価格(INT)としておけば枚数割引が商品によって異なる場合などでも対応できるようになる

<?php
$con = mysql_connect(接続) or die 'システムエラー1';
mysql_select_db(データベース名) or die 'システムエラー2';
$sql = "SELECT * FROM テーブル名"
     . " WHERE 種類='" . mysql_real_escape_string($_POST['select']) . "'"
     . " AND 版代='" . mysql_real_escape_string($_POST['select2']) . "'"
     . " AND 枚数=" . mysql_real_escape_string($_POST['select3']);
$res = mysql_fetch_assoc($con) or die 'システムエラー3';
echo $res['価格'];
mysql_close($con);
?>

さらに効率をあげたい場合は・・・ケースバイケースなので、ひとまずこの辺で

id:kasai-de_eb

分かりやすご回答をいただき有難うございました。

とっても参考になりました。

2010/05/26 15:42:37
id:doropon No.3

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

ポイント13pt

御希望の機能はjavascriptですね。

phpで計算するのであれば、ajaxで非同期に通信してフォームを更新する必要があります。

金額などのデータをhtmlに埋め込むか、json形式でサーバに置いておくか。

php単体だと画面の更新でユーザビリティが低下するのでお気を付けください。

id:tobeoscontinue No.4

回答回数220ベストアンサー獲得回数59

ポイント25pt
<?php
function attr($args) {
  $attribute = '';
  foreach ($args as $key=>$value)
    $attribute .= ' '.$key.'="'.$value.'"';
  return $attribute;
}
function tag($name, $value) { return '<'.$name.">{$value}</{$name}>"; }
function b($value) { return tag('b', $value); }
function submit($name, $value='') {
  return '<input type="submit" name="'.$name.'" value="'.$value.'">';
}

function textarea($name, $value='') {
  return '<textarea name="'.$name.'" readonly>'.$value.'</textarea>';
}

function menu($name, $value, $list) {
  $selected = $list["$value"];
  $options = '';
  foreach ($list as $key=>$value)
    $options .= '<option value="'.$key.'"'.
      (($value == $selected) ? 'selected' : '').'>'.$value.'</option>';
  return '<select name="'.$name.'">'.$options.'</select>';
}

function form($fields, $action='.',$method='POST') {
  return '<form action="'.$action.'" method="'.$method.'">'.$fields.'</form>';
}

function tr($row, $td='') {
  foreach ($row as $id=>$cell) {
    $attr = (isset($GLOBALS['ATTR']["$id"])) ? ' '.attr($GLOBALS['ATTR']["$id"]) : '';
    $td .= '<td'.$attr.'>'.$cell.'</td>';
  }
  return $td;
}

function table($matrix, $tdody='') {
  foreach ($matrix as $id=>$row) {
    $attr = (isset($GLOBALS['ATTR']["$id"])) ? attr($GLOBALS['ATTR']["$id"]) : '';
    $tbody .= '<tr'.$attr.'>'.tr($row).'</tr>';
  }
  return tag('table', $tbody);
}

function validate($list, $method) {
  $vars = array();
  foreach ($list as $name=>$org)
    if (isset($method["$name"]))
      if (isset($org)) {
        if (isset($org[$method["$name"]])) $vars["$name"] = $method["$name"];
      } else  $vars["$name"] = $method["$name"];
  return $vars;
}
 
$category = array('T100'=>'T100');
$plate = array(10=>'10cm角', 20=>'20cm角');
$number= array(1=>'1枚',2=>'2枚');

$args = array('select'=>$category,'select2'=>$plate,'select3'=>$number);
$vars = validate($args, $_POST);

if (count($vars) == 3) {
  extract($vars);
  $price = array(
    'category'=>array('T100'=>0),
    'plate'=>array(10=>3000,20=>5000),
    'number'=>array(1=>1000,2=>1800));
  $outbox = '見積り価格: '.($price['category']["$select"]+
                          $price['plate']["$select2"]+
                          $price['number']["$select3"]).'';
} else {
  $select = 'T100';
  $select2= 10;
  $select3= 1;
  $outbox = 'ここに計算結果が表示されます';
}

$ATTR['td1'] = array('class'=>'label');

$quotable = array(
  array('td1'=>b('種類'), menu('select',$select,$category)),
  array('td1'=>b('名入れ版代'), menu('select2',$select2,$plate)),
  array('td1'=>b('枚数'), menu('select3',$select3,$number)));

$debug= print_r($vars, TRUE);
$form = form(table($quotable).'<br>'.submit('calculate','計算'), $_SERVER[SCRIPT_NAME])
        .textarea('outbox',$outbox);

echo <<<EOS
<html>
<head>
<style type="text/css">
 div div{width:320px; background-color:#ffffff;}
 table{width:100%; border-collapse:collapse;}
 td{border-width:1px; border-style:solid; border-color:#a0a0a0; padding:10px;}
 .label{width:90px;  background-color:#e0ffff;}
 textarea{width:100%; height:4em; font-size:20px; background-color:#ff9900; padding:10px; border-width:1px; border-style:solid;}
</style>
</head>
<body>
<div align="center">$debug<div>$form</div></div>
</body>
EOS;

phpでformの部分の処理は面倒な部分です。

1) 一般的な流れとしては入力をするためのformのhtmlを出力する部分と、

2) 入力された値をチェックし、計算をした後の値を出力する部分です。

これらは一つのことについてしているのですがすべきことが大きく違います。

HTML_QuickFormが便利だと思うのですが助長のように思い似た感じの処理を目指していサンプルを書いてみました。。肝としては<input>などのnameとphpでの変数名との対応をとることかなぁと思っています。

サンプルコードのattr,tag,b,submit,textarea,menu,form,tr,tableはhtmlを生成しているだけの部分です。

この目的はphpコードとhtmlコードが混ざらないようにして可読性を上げるためです。もう一つは例えば配列要素を追加するだけでhtmlコードが生成されるので便利です。ただこうするとhtmコードの自由度が低下する弊害もあります。

データベーズについては考慮していません。結局は変数でアクセスするわけですから。

$category,$plate,$numberは<select>を生成するためのデータでこの形式に合わせる必要があります。

$argsは名前とそれが取りうる値のペアーです。(想定しない値が入力されないよう)

$ATTRはタグの属性を設定するためのグローバル変数。いい実装とはいいがたいorz。

$debugは確認用で、削除してかまいません。

処理としてはvalidateで$_POSTの中に'select','select2','select3'などの名前のものがあれば取り出しその値の妥当性をチェックします。

3つ取り出せれば、その値は妥当であると仮定し見積り金額を計算します。それ以外では入力が無いものとします。

つまりvalidateで1)か2)かが判断されます。

後はform(),table(),submit(),textarea()などでhtmlを生成するだけです。

単純なhtmlでは一部分だけの変更でもサーバーから全ソースを送り出して再描画したとしても視覚的にはさほど違和感は無いと思います。

またJavaScriptが切ってあっても動作可能でし、金額など隠蔽しやすい利点もあります。

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

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

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

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