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

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

ただいまの
回答率

90.75%

  • PHP

    19209questions

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

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

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 126

kotetsu0521

score 2

 前提・実現したいこと

現在、注文入力画面→結果表示画面を作成しています。(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/ツールのバージョンなど)

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

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


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

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]:"なし");
         }
        // ★ここ、foreach終了時点で、$keyの値は常に同じです($pnkの最後の添え字)
        // ★その$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";
    }
}

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


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

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!=="";
    });
}


↑これ、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と比較し該当の添え字を見つけるのでもいいです。

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

foreach($rows as $row){
  foreach(["partsnumber","description","unitprice","stockqty"] as $val){
    //ここは省略
  }
  foreach($pnk as $key=>$val){
    //同じ部品番号の時に、テーブルを出力する
    if($val == $partsnumber){
     //表示用の数量
      $show_qty = 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">{$show_qty}</div></th>
eof;
      print "<tr>\n";

      //これ以降の$pnkのループは不要なので、処理を抜けます。
      break; 
    }
  }
}

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

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

foreach($rows as $row){
  foreach(["partsnumber","description","unitprice","stockqty"] as $val){
    //ここは省略
  }
  //該当の添え字(キー)を探す。
  $key = array_search($partsnumber, $pnk);
  if($key !== false) { continue; }// 念の為、添え字が見つからなかったら次の処理へ・・
  //表示用の数量
  $show_qty = 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">{$show_qty}</div></th>
eof;
  print "<tr>\n";
}

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

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

foreach(["pnk","qty"] as $val){
//中身は省略
}

if(count($pnk) == 0){
  print "<p>入力エラー:部品番号を入力してください</p>\n";
}else{
  //続きの処理はここから・・・
  try{    
     //(SQLサーバーへ接続)
 。。。以下略

}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/06 18: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が正しく表示されない。

    説明が下手でわかりにくくてすみません・・・。

    キャンセル

  • 2018/06/06 18: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」は、欠如してしまうはずですよ。というお話です。
    なので数量に全部違う数字を入れて動作確認をしているのであれば、この問題は発生しません。。。

    キャンセル

  • 2018/06/07 16: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";

    テーブル表示にこだわり過ぎているのかもしれませんが、他のページのレイアウトの兼ね合いもありどうしてもこの表に当てはめたいのです。度々で申し訳ありませんが余計なループをしなくてすむようにアドバイスをお願いします。

    キャンセル

  • 2018/06/08 11:11

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

    キャンセル

  • 2018/06/08 17:39

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

    キャンセル

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

  • ただいまの回答率 90.75%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • PHP

    19209questions

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