みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

HTML+PHPのリストボックス表示について

現在HTML+PHPで勉強しながらアプリを作成しています。
MySQLからデータをよみ、その値からリストボックスを作成し表示させていますが、そのリストボックスがテーブル内に表示されず、位置がずれて表示されます。どうすればうまくテーブル内に表示されるのか教えてください。よろしくお願いします。(PHPというよりHTMLの質問かもしれませんが)

<?php
//データベース接続設定
$dbtype="mysql";
$sv="localhost";
$dbname="hogehoge";
$user="root";
$pass="abcdefg";

//データベースに接続
$dsn = "$dbtype:dbname=$dbname;host=$sv";
$conn = new PDO($dsn,$user,$pass);
//----------------------------------------
// ■ POST時
//----------------------------------------
if ($_SERVER["REQUEST_METHOD"]=="POST"){
// □ 新規追加
if (isset($_POST["submit_add"])){
$new_code = htmlspecialchars($_POST["new_code"], ENT_QUOTES);//追加コード
$new_kbncod = htmlspecialchars($_POST["new_kbncod"], ENT_QUOTES);//追加項目
$sql = "INSERT INTO kekka VALUES(null,'$new_code','$new_kbncod')";
$stmt = $conn->prepare($sql);
$stmt->execute();
}
// □ 変更
if (isset($_POST["submit_upd"])){
$id = key($_POST["submit_upd"]);//押下したボタン番号を取得
//--------------------------------
// □ POSTされたデータを取得
//--------------------------------
$upd_kbncod = htmlspecialchars($_POST["kbn_code"][$id], ENT_QUOTES);//変更項目
$upd_code = htmlspecialchars($_POST["code"][$id], ENT_QUOTES);//変更コード

$sql = "UPDATE kekka SET code = $upd_code, kbn_code = $upd_kbncod WHERE id=$id";
$stmt = $conn->prepare($sql);
$stmt->execute();
}
// □ 削除
if (isset($_POST["submit_del"])){
$id = key($_POST["submit_del"]);//押下したボタン番号を取得
//テーブルからデータを削除
$sql = "DELETE FROM kekka WHERE (id = $id)";
$stmt = $conn->prepare($sql);
$stmt->execute();
}
}
//=====================================================================
// ■ H T M L
//=====================================================================
?>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>テスト</title>
</head>
<body>
<h1>テスト中</h1>
<form action="<?=$_SERVER['SCRIPT_NAME']?>" method="POST">
<table border="1" cellspacing="0" cellpadding="3" width="100%" bordercolor="#666666">
<tr bgcolor="#eee8aa">
<td align="center"><font size="2">項目名(リスト)</font></td>
<td align="center"><font size="2">コード:数字4桁</font></td>
<td align="center"><font size="2">ボタン</font></td>
</tr>
<?php
//----------------------------------------
// □:テーブルからデータを読む
//----------------------------------------
$sql = "SELECT * FROM kekka ORDER BY id";
$stmt = $conn->prepare($sql);
$stmt->execute();
while($row = $stmt->fetch()){
$id = $row["id"];
$code = $row["code"];
$kbncod = $row["kbn_code"];
echo "<td>".disp_list($conn,"code_hyo", "KBN_CODE", "KBN_NAME", $kbncod, "kbn_code[$id]")."</td>";
echo "<td><input type=text name=code[$id] value=$code size=10></td>";
echo "<td><input type=submit name=submit_upd[$id] value='変更' size=4>";
echo "<input type=submit name=submit_del[$id] value='削除' size=4></td>";
echo "</tr>";
}
//追加リスト表示用に、変数の初期化を行う。(ゴミデータ除去)
$kbncod="";
$code="";
$new_kbncod="";
$new_code="";
?>

<tr>
<td><?php echo disp_list($conn,"code_hyo", "KBN_CODE", "KBN_NAME", $new_kbncod, "new_kbncod"); ?></td>
<td><input type="text" name="new_code" value="<?=$new_code ?>" size="15"></td>
<td><input type="submit" name="submit_add" value="追加" size="4"></td>
</tr>
</table>
</form>
</body>
</html>
<?php
// パラメータ:接続/テーブル名/リスト値/表示値/選択値/リスト名称
function disp_list( $conn2,$table, $value, $text,$selected_value, $m_name) {
// DBから項目情報を取り出す
$sql2 = "SELECT * FROM " . $table . " ORDER BY " . $value;
$stmt2 = $conn2->prepare($sql2);
$stmt2->execute();

// 取り出した項目情報をプルダウンリストに表示する
echo "<select name=\"" . $m_name . "\">";
while ($row2 = $stmt2->fetch()){
echo "<option ";
if ($selected_value == $row2[$value]) {
echo " selected ";
}
echo " value=\"".$row2[$value]."\">";
echo $row2[$text]."</option>";
}
echo "</select>";
}
?>

投稿日時 - 2013-09-13 22:21:51

QNo.8262697

すぐに回答ほしいです

質問者が選んだベストアンサー

まともにデバッグ出来てないですがこういう実装でどうでしょうか・・・?
恐らく何か所かミスしてると思うので注意深く見てみてください。(デバッグ丸投げすみません)
disp_list関数に関しては逆に分かりにくくなると思ったので今回はそのまま書きました。
http://codepad.org/eJ9SO136

投稿日時 - 2013-09-14 15:44:18

お礼

素晴らしいです!(誤記はありましたが、私でもすぐわかるレベルの程度の問題でした)例外処理等も追記していただきありがとうございます!動作自体は私が望んでいるものでしたので、記載していただいたソースをちょっと自分なりに解析してみます。本当に助かりました!!

投稿日時 - 2013-09-14 17:47:22

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.2

サンプルを作っていたのですが、途中でどうも理解できなかったことがあるので一旦ここで中断させていただきます。
http://codepad.org/fOxpAAnW

kekkaテーブルとcode_hyoテーブルはどうして別になっているんでしょうか?
全くその意図が分かりませんでした。
また、各カラムの意味とdisp_list関数もいまいち分からないので説明お願いします。

以下キリが無いですが指摘入れます。

・MySQLのカラム名は全て小文字にしてください。大文字を使うと定数や予約語と紛らわしくなります。

・HTMLとPHPを可能な限り分離させてください。echoでべた書きしていると非常に読みづらくなります。

・htmlspecialchars関数ではSQLインジェクション対策にエスケープしたことになりません。むしろ正しいクエリを送信しようとしても意図していないものに書き換えられる可能性すらあります。正しいクエリ実行方法については先ほどURLを掲載した私のQiitaの記事を参照してください。

・変数のスコープについて学んでください。「$conn2」「$row2」などの変数が使われているところを見るとスコープに対する理解が無いように見えます。 http://php.net/manual/ja/language.variables.scope.php

・本題に戻りますが、PHPを触る以前にHTMLについてもう少し学んだ方がいいように見えます。今回のトラブルの直接の原因は<tr>の書き忘れですが、それにとどまらず非推奨要素・非推奨属性についても知っておいた方がいいと思います。<font>は代表的な非推奨要素です。今時使っているとバカにされるぐらいです。bgcolor属性も非推奨です。その他cellpadding,cellspacing属性などもCSSに任せられるので可能な限り使わないほうがいいです。

投稿日時 - 2013-09-14 01:02:23

補足

・kekkaテーブルとcode_hyoテーブルについて別にしている理由は、code_hyoテーブルと同じような内容のマスターテーブルを複数作成する必要がありそれらを同じようにリスト表示させる為に分けています。kekkaテーブルはcodeに対して、KBN_CODEと同じようなコードを複数紐付けさせる事になります。更にkekkaテーブルからCSVでデータを引っ張るという要求もあるので、そこにあ保持させてます。kekkaテーブルと同じようなテーブルが増えるので、関数にしてリスト表示で使いまわせればと思っている次第です。(クラス化すべきかもしれませんが)

・大文字/小文字の件はご指摘通りです。以降変更します。
・echoべた書きの件もご指摘通りなのですが、まずは動作させる事を第一にし質問させていただきましたので見苦しい点はお許しください。(綺麗なソースコードが解りやすくBugも減る事は知っていますが、そこまで技術力がついていません)
・htmlspecialchars関数だけで脆弱性チェックを終わらせるつもりはありませんので、ぜひ記事を参考にさせていただきます。スコープの件も分ける必要がないのは解りますが、自分が混乱してしまう為に、現状あえて分けてます。
・非推奨要素/属性については全てではありませんが存じております。後で表示周りはCSSで対応させる予定ではありますが、まだそこまで全然手が回っていないのです(学習もです)。

以上、説明不足している部分もあるかと思いますが、ご丁寧に指摘ありがとうございます。

投稿日時 - 2013-09-14 02:23:17

ANo.1

質問とは直接関係ないですがとりあえずこちらをご一読ください。
脆弱性に気づいていただければ幸いです。
http://qiita.com/mpyw/items/b00b72c5c95aac573b71

後ほどまた追記します。

投稿日時 - 2013-09-13 23:06:34

あなたにオススメの質問