質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

935閲覧

SQLデータとPOSTデータを同時に表示させるには

kotetsu0521

総合スコア8

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2018/06/06 06:15

前提・実現したいこと

現在、注文入力画面→結果表示画面を作成しています。(or検索してます。←これは絶対条件)
htmlの「注文入力画面」に「pnnmber」と「qty(注文数)」を10件入力できるようにしてあります。この「pnnmber」と「qty」は対です。
例)pnnmber「123456」qty「3」と入力した場合 123456を3個注文といった解釈になります。
htmlで入力後「order(まだ仮)」ボタンを押すと結果表示画面に移動します。(phpファイル)
php内でSQLサーバーへ接続し「pnnmber」の情報(pnnmber、商品名、価格、在庫数)とhtmlで入力した「qty」をすでに作成している表示用テーブルに当てはめたいのですが、表示用テーブルにはSQLサーバーから取り出した情報は表示できているのですが、POSTしてきた「qty」がうまく表示されません。
どうか、表示したい場所に結果が表示できるようにアドバイスをお願い致します。

発生している問題・エラーメッセージ

現在の状態・・・
注文入力画面にpnnmber「123456」qty「3」とpnnmber「234567」qty「4」と入力して結果表示画面へ移動すると、

pnnmber、商品名、価格、在庫数は「123456」および「234567」に対応する情報が表示されます。
「qty」は「234567」の行に入力した「4」が「123456」と「234567」の結果として表示されてしまいます。

わかりやすいようにhtmlの入力時とphpの結果画面を添付しました。

該当のソースコード

-order_input.html-

<td><form method="post" action="order_input_view.php"> <p><input class="pnnmber" type="text" name="pnk[1]" placeholder="部品番号"><input class="suryo" type="text" name="qty[1]" placeholder="数量"></p> <p><input class="pnnmber" type="text" name="pnk[2]" placeholder="部品番号"><input class="suryo" type="text" name="qty[2]" placeholder="数量"></p> </div>

以降nameを[3]・・・として[10]まであります。

イメージ説明

-order_input_view.php-

<?php foreach(["pnk","qty"] as $val){ $$val=filter_input(INPUT_POST,$val,FILTER_DEFAULT,["options"=>["default"=>[]],"flags"=>FILTER_REQUIRE_ARRAY]); $$val=array_filter(array_unique($$val),function($x){ return $x!==""; }); } if(count($pnk)>0){ foreach($pnk as $key=>$val){ } } try{ (SQLサーバーへ接続) $sql='SELECT partsnumber,description,unitprice,stockqty FROM parts_price WHERE 1 '; $data=[]; if(count($pnk)>0){ $sql.="and partsnumber in("; $sql.=implode(array_fill(0,count($pnk),"?"),","); $sql.=")"; $data=array_merge($data,$pnk); } /*デバック用 print $sql."<br>"; print_r($data); */ $stmt = $dbh->prepare($sql); $stmt->execute($data); $rows=$stmt->fetchAll(); } catch(PDOException $e) { die($e->getMessage()); } ?> <table width="80%" class="aaa"> <td scope="col"><div id="sent16_stl_cen">Parts Number</div></td> <td scope="col"><div id="sent16_stl_cen">Description</div></td> <td scope="col"><div id="sent16_stl_cen">Unit Price</div></td> <td scope="col"><div id="sent16_stl_cen">Stock</div></td> <td scope="col"><div id="sent16_stl_cen">suryo</div></td> <?php print "<tr>\n"; foreach($rows as $row){ foreach(["partsnumber","description","unitprice","stockqty"] as $val){ if($val=="unitprice") $row[$val]=number_format($row[$val]); $$val=htmlspecialchars($row[$val]); } if(count($pnk)>0){ foreach($pnk as $key=>$val){ (isset($qty[$key])?$qty[$key]:"なし");} print <<<eof <th class="th"><div id="sent14_stl">{$partsnumber}</div></th> <th class="th"><div id="sent14_stl">{$description}</div></th> <th class="th" align="right"><div id="sent14"_stl>{$unitprice}</div></th> <th class="th"><div id="sent14_stl">{$stockqty}</div></th> <th class="th"><div id="sent14_stl">{$qty[$key]}</div></th>**←ここにqtyを表示させたい** eof; print"<tr>\n"; } } ?>
</table>

イメージ説明

試したこと

<th class="th"><div id="sent14_stl">{$qty[$key]}</div></th> {}内を色々と変更してみました。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

本物のコードがこうなのか分からないですが、
入れ子になっている部分が、どのタイミングで処理されているのかが分かりにくいので、
もっとインデントをそろえた方が良いですよ。


質問についての原因。
コードにコメントで書き足しています。(//★部分)

php

1print "<tr>\n"; 2foreach($rows as $row){ 3 foreach(["partsnumber","description","unitprice","stockqty"] as $val){ 4 if($val=="unitprice") $row[$val]=number_format($row[$val]); 5 $$val=htmlspecialchars($row[$val]); 6 } 7 8 if(count($pnk)>0){ 9 foreach($pnk as $key=>$val){ 10 (isset($qty[$key])?$qty[$key]:"なし"); 11 } 12 // ★ここ、foreach終了時点で、$keyの値は常に同じです($pnkの最後の添え字) 13 // ★その$keyを使って、数量{$qty[$key]}を出しているので、いつでも同じ値になると思います。 14 print <<<eof 15 16 <th class="th"><div id="sent14_stl">{$partsnumber}</div></th> 17 <th class="th"><div id="sent14_stl">{$description}</div></th> 18 <th class="th" align="right"><div id="sent14"_stl>{$unitprice}</div></th> 19 <th class="th"><div id="sent14_stl">{$stockqty}</div></th> 20 <th class="th"><div id="sent14_stl">{$qty[$key]}</div></th>**←ここにqtyを表示させたい** 21 eof; 22 print"<tr>\n"; 23 } 24}

$qty[$key] としたいのであれば、
$rowの$partsnumberと同じ値を $pnk から探し、その添え字を$keyに入れるべきかと。


質問以外の部分で、他にも何点か気になるところはあったのですが、
とりあえず一番気になる部分だけ、余計なお世話がてらに、書いてみます。

php

1foreach(["pnk","qty"] as $val){ 2 $$val=filter_input(INPUT_POST,$val,FILTER_DEFAULT,["options"=>["default"=>[]],"flags"=>FILTER_REQUIRE_ARRAY]); 3 $$val=array_filter(array_unique($$val),function($x){ 4 return $x!==""; 5 }); 6}

↑これ、pnkとqtyの両方を array_uniqueしていますよね。

通常の買い物を考えると、「商品」が異なっても「購入数(数量)」は同じ、は有り得ると思うのですが、
array_uniqueすることで、「購入数(数量)」のデータが欠如する可能性が高そうですが、大丈夫なのでしょうか?

コメントからの追記

pnk「123456」qty「3」とpnk「234567」qty「4」を入力した場合、送られてきた値は、
↓のような感じ・・部品番号と数量は、「添え字」の同じものが対ですね。

//部品番号 $pnk = [1=> 123456, 2 => 234567]; //数量 $qty = [1=> 3, 2 => 4];

この$pnkを条件に取得したデータ$rowsは、

$rows = [ 0 => ["partsnumber" => 123456, "description" => '部品A', "unitprice" => 100, "stockqty" => 1000], 1 => ["partsnumber" => 234567, "description" => '部品B', "unitprice" => 200, "stockqty" => 2000] ];

こんな感じの内容かと、想像します。(partsnumber以外は、カラム名から適当な値を入れています。)

$rowsの1レコード($row)には$partsnumberがあり、
この$partsnumberは、$pnkの配列のに必ずある「値」である、という想定になります。

つまり、
配列[$pnk]の中から該当する値[$partsnumber]の添え字が分かれば、
数量も同じ添え字を使って表示することが出来ます。

php初心者さんのようですので、
自分で$pnkをループして、$partsnumberと比較し該当の添え字を見つけるのでもいいです。

今のコードを流用するなら、こんな感じでしょうか。

php

1foreach($rows as $row){ 2 foreach(["partsnumber","description","unitprice","stockqty"] as $val){ 3 //ここは省略 4 } 5 foreach($pnk as $key=>$val){ 6 //同じ部品番号の時に、テーブルを出力する 7 if($val == $partsnumber){ 8  //表示用の数量 9 $show_qty = isset($qty[$key]) ? $qty[$key]:"なし"; 10 print <<<eof 11 <th class="th"><div id="sent14_stl">{$partsnumber}</div></th> 12 <th class="th"><div id="sent14_stl">{$description}</div></th> 13 <th class="th" align="right"><div id="sent14"_stl>{$unitprice}</div></th> 14 <th class="th"><div id="sent14_stl">{$stockqty}</div></th> 15 <th class="th"><div id="sent14_stl">{$show_qty}</div></th> 16eof; 17 print "<tr>\n"; 18 19 //これ以降の$pnkのループは不要なので、処理を抜けます。 20 break; 21 } 22 } 23}

自分でループさせずとも、「配列から、指定した値と同じ最初のキー(添え字)を探す」array_searchという便利な関数もあります。
※結果として「0」と「false」が戻ってくる関数ですので、使い方はリファレンスをよく読んでくださいね。

array_searchを使うなら、こんな感じです。

php

1foreach($rows as $row){ 2 foreach(["partsnumber","description","unitprice","stockqty"] as $val){ 3 //ここは省略 4 } 5 //該当の添え字(キー)を探す。 6 $key = array_search($partsnumber, $pnk); 7 if($key !== false) { continue; }// 念の為、添え字が見つからなかったら次の処理へ・・ 8 //表示用の数量 9 $show_qty = isset($qty[$key]) ? $qty[$key]:"なし"; 10 //テーブルを出力する 11 print <<<eof 12 <th class="th"><div id="sent14_stl">{$partsnumber}</div></th> 13 <th class="th"><div id="sent14_stl">{$description}</div></th> 14 <th class="th" align="right"><div id="sent14"_stl>{$unitprice}</div></th> 15 <th class="th"><div id="sent14_stl">{$stockqty}</div></th> 16 <th class="th"><div id="sent14_stl">{$show_qty}</div></th> 17eof; 18 print "<tr>\n"; 19}

ちなみにですが、上記のコードでは、
$pnkのカウントが0の場合は、テーブルの出力結果が無いので、$rowsを回して処理をする必要がありません・・・というよりも、そもそも$rowsの取得自体が無駄と言えます。

なので、最初の方で、この判別をしてしまうのが効率的です。

php

1foreach(["pnk","qty"] as $val){ 2//中身は省略 3} 4 5if(count($pnk) == 0){ 6 print "<p>入力エラー:部品番号を入力してください</p>\n"; 7}else{ 8 //続きの処理はここから・・・ 9 try{ 10 //(SQLサーバーへ接続) 11 。。。以下略 12 13}

投稿2018/06/06 07:42

編集2018/06/08 02:10
mix-peach

総合スコア1910

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kotetsu0521

2018/06/06 09:04

さっそくありがとうございました。ご指摘いただいたforech部分ですが、SQLサーバーに接続する前に下記のようになコードにするとpnnmberとpnnmberに対するhtmlで入力したqtyが問題なく表示されます。 なのでデータ自体はarray_uniqueしても欠如してない・・・と思います。 if(count($pnk)>0){ print "<table border>\n"; print "<tr><th>pnk</th><th>suryo</th></tr>\n"; foreach($pnk as $key=>$val){ print "<tr>\n"; print "<td>{$val}</td><td>".(isset($qty[$key])?$qty[$key]:"なし")."</td>\n"; print "</tr>\n"; } print "</table>\n"; ですが、これをSQLサーバ接続後の「ここに表示させたい!」と思うテーブル内で表示させようとすると、質問させていただいたような結果になるのです。 サーバ接続前→or検索(対象は$pnk)でヒットしたpartsnumber+入力したqtyが表示される。 サーバ接続後→or検索でヒットした$pnkに対する情報は表示されるがqtyが正しく表示されない。 説明が下手でわかりにくくてすみません・・・。
mix-peach

2018/06/06 09:32

SQLサーバ接続後・・・とかは、関係ないです。 コメントのコードの (isset($qty[$key])?$qty[$key]:"なし") と、 質問のコードの $qty[$key] は、処理のタイミングが違うのです。 コメントの方は、 foreach($pnk as $key=>$val) の中で$keyが動的に変更されている部分で (isset($qty[$key])?$qty[$key]:"なし") に使っているので、正しい $qty の数字が出ます。 質問のコードは、 foreach($pnk as $key=>$val)の処理が全て終わった後に、 $qty[$key] としていますよね。 回答にも書きましたが、foreachを抜けた後、$keyの値は、いつでも$pnkの最後の添え字になります。 そのため、$pnkの最後の「商品コード」に書いたはずの「数量」が、全ての「商品コード」の「数量」として表示されるのです。 array_uniqueの指摘は、例えば、 pnnmber「123456」qty「3」とpnnmber「234567」qty「3」としたような時に、234567のqty「3」は、欠如してしまうはずですよ。というお話です。 なので数量に全部違う数字を入れて動作確認をしているのであれば、この問題は発生しません。。。
kotetsu0521

2018/06/07 07:41

お世話になっております。 コードの位置を変更したり色々とやりながら、なんとか表示したい場所をforeach文の中にして、qtyは表示されるようになりました。 ですが、当たり前ですがすべてがループをするようになってしまい、3アイテムをhtmlに入力して画面を移動させると3アイテムが3回(計9行)表示されてしまいます。 if(count($pnk)>0){ foreach($pnk as $key=>$val){ isset($qty[$key])?$qty[$key]:"なし"; print <<<eof <th class="th"><div id="sent14_stl">{$partsnumber}</div></th> <th class="th"><div id="sent14_stl">{$description}</div></th> <th class="th" align="right"><div id="sent14"_stl>{$unitprice}</div></th> <th class="th"><div id="sent14_stl">{$stockqty}</div></th> <th class="th"><div id="sent14_stl">{$qty[$key]}</div></th> eof; print"<tr>\n"; テーブル表示にこだわり過ぎているのかもしれませんが、他のページのレイアウトの兼ね合いもありどうしてもこの表に当てはめたいのです。度々で申し訳ありませんが余計なループをしなくてすむようにアドバイスをお願いします。
mix-peach

2018/06/08 02:11

長くなったので、回答に追記しました!
kotetsu0521

2018/06/08 08:39

ありがとうございました!!!! 希望通りの結果表示ができるようになりました。 しかも他の書き方まで丁寧に教えていただいて・・・。今回使用しなかったarry・・・のほうは他のファイルで利用させていただきたいと思います。 また、おっしゃる通り素人でございます。基礎の基礎から受講するなり通学するなりできればいいのでしょうが、そうもいかず・・・。なので、複雑な仕組みなになるとまるっきり八方ふさがりになってしまいます。 素人にはこのように根気よくアドバイスしていただける方、この場を提供してくれる方々には本当に感謝しかありません。 本当にありがとうございました。また解決できないことがあれば質問させていただきたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問