現在PHPとMySQLの学習をしています。
詳細! PHP 7+MySQL 入門ノート(大重 美幸 (著))にあるトランザクション処理を参考に自分のMacのMAMP上で実行しているのですが、どうしてもわからないことがあり、質問させて頂きます。
テーブルは下記の3つです。
(1)mainテーブルを中心に、(2),(3)とリレーションしています。
フォームから入力すると、DB上に商品が増えて行きたいのですが、
うまく出来ていません。
フォームの表示、入力までは出来ているように見えるのですが、
confirm.php を見ると、
タイトルが空です。
材料が空です。
という表示が出てしまい、
データベースの方にもデータが格納されていません。
わからないことは、
- テーブルの組合せがこれで大丈夫なのか(単純ですが間違っているのか)
- confirm.php の、エラー処理で引っかかっているのですが、ここがおかしいのでしょうか
php
1 // 簡単なエラー処理 2 $errors = []; 3 if (!isset($_POST["id"])||($_POST["id"]==="")){ 4 $errors[] = "IDが空です。"; 5 } 6 7 if (!isset($_POST["table_name"])||($_POST["table_name"]==="")){ 8 $errors[] = "タイトルが空です。"; 9 } 10 11 if (!isset($_POST["material_name"])||($_POST["material_name"]==="")) { 12 $errors[] = "材料が空です。"; 13 }
アドバイスを頂けたら幸いです。
(1) mainテーブル
id(主キー) | id_title(外部キー) | id_material(外部キー) |
---|---|---|
(2) 番号リストtable_titleテーブル
id_title(主キー) | title_ja |
---|---|
(3) table_materialテーブル
-- あらかじめ材料は入力し、フォームから選択する
id_material(主キー) | material_name |
---|---|
コードは下記が
- form.php
php
1<?php 2require_once("util.php"); 3$gobackURL = "insertform.html"; 4 5// データベースユーザ 6$user = '----'; 7$password = '----'; 8// 利用するデータベース 9$dbName = '----'; 10// MySQLサーバ 11$host = '----'; 12// MySQLのDSN文字列 13$dsn = "mysql:host={$host};dbname={$dbName};charset=utf8"; 14//MySQLデータベースに接続する 15try { 16 $pdo = new PDO($dsn, $user, $password); 17 // プリペアドステートメントのエミュレーションを無効にする 18 $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 19 // 例外がスローされる設定にする 20 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 21 22 // ブランドテーブルから材料IDと材料名を取り出す 23 $sql = "SELECT id_material, material_name FROM table_material"; 24 // プリペアドステートメントを作る 25 $stm = $pdo->prepare($sql); 26 // SQLクエリを実行する 27 $stm->execute(); 28 // 結果の取得(連想配列で受け取る) 29 $table_material = $stm->fetchAll(PDO::FETCH_ASSOC); 30} catch (Exception $e) { 31 $err = '<span class="error">エラーがありました。</span><br>'; 32 $err .= $e->getMessage(); 33 exit($err); 34} 35?> 36 37<!DOCTYPE html> 38<html lang="ja"> 39<head> 40<meta charset="utf-8"> 41<title>レコード追加</title> 42</head> 43<body> 44<div> 45 <!-- 入力フォームを作る --> 46 <form method="POST" action="confirm.php"> 47 <ul> 48 <li> 49 <label>ID: 50 <input type="text" name="id" placeholder="ID"> 51 </label> 52 </li> 53 <li> 54 <label>商品名: 55 <input type="text" name="table_name" placeholder="商品名"> 56 </label> 57 </li> 58 <li>材料: 59 <select name="table_material"> 60 <?php 61 // 材料は材料テーブルに登録してあるものから選ぶ 62 foreach ($table_material as $row){ 63 echo '<option value="', $row["id_material"], '">', $row["material_name"], "</option>"; 64 } 65 ?> 66 </select> 67 </li> 68<!-- <li> 69 <label>個数: 70 <input type="number" name="quantity" placeholder="半角数字"> 71 </li> --> 72 <li><input type="submit" value="追加する"></li> 73 </ul> 74 </form> 75</div> 76</body> 77</html> 78 79 80
- confirm.php
php
1<?php 2require_once("util.php"); 3$gobackURL = "form.php"; 4 5// 文字エンコードの検証 6if (!cken($_POST)){ 7 header("Location:{$gobackURL}"); 8 exit(); 9} 10?> 11 12<!DOCTYPE html> 13<html lang="ja"> 14<head> 15<meta charset="utf-8"> 16<title>レコード追加</title> 17</head> 18<body> 19<div> 20 21<?php 22 // 簡単なエラー処理 23 $errors = []; 24 if (!isset($_POST["id"])||($_POST["id"]==="")){ 25 $errors[] = "IDが空です。"; 26 } 27 if (!isset($_POST["table_name"])||($_POST["table_name"]==="")){ 28 $errors[] = "タイトルが空です。"; 29 } 30 if (!isset($_POST["material_name"])||($_POST["material_name"]==="")) { 31 $errors[] = "材料が空です。"; 32 } 33 34 //エラーがあったとき 35 if (count($errors)>0){ 36 echo '<ol class="error">'; 37 foreach ($errors as $value) { 38 echo "<li>", $value , "</li>"; 39 } 40 echo "</ol>"; 41 echo "<hr>"; 42 echo "<a href=", $gobackURL, ">戻る</a>"; 43 exit(); 44 } 45 46 47// データベースユーザ 48 $user = '----'; 49 $password = '----'; 50 // 利用するデータベース 51 $dbName = '----'; 52 // MySQLサーバ 53 $host = '----'; 54 // MySQLのDSN文字列 55 $dsn = "mysql:host={$host};dbname={$dbName};charset=utf8"; 56 57 //MySQLデータベースに接続する 58 try { 59 $pdo = new PDO($dsn, $user, $password); 60 // プリペアドステートメントのエミュレーションを無効にする 61 $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 62 // 例外がスローされる設定にする 63 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 64 } catch (Exception $e) { 65 $err = '<span class="error">エラーがありました。</span><br>'; 66 $err .= $e->getMessage(); 67 exit($err); 68 } 69 70 try { 71 // トランザクションを開始する 72 $pdo->beginTransaction(); 73 // SQL文を作る 74 $sql1 = "INSERT INTO table_material (id_material, material_name) 75 VALUES (:id_material, :material_name)"; 76 77 $sql2 = "INSERT INTO table_title (id_name, name) VALUES (:id_name, :name)"; 78 // プリペアドステートメントを作る 79 $insertGoods = $pdo->prepare($sql1); 80 $insertStock = $pdo->prepare($sql2); 81 82 // プレースホルダに値をバインドする 83 $insertGoods->bindValue(':id_material', $_POST["id_material"], PDO::PARAM_STR); 84 $insertGoods->bindValue(':material_name', $_POST["material_name"], PDO::PARAM_STR); 85 86 $insertStock->bindValue(':id_name', $_POST["id_name"], PDO::PARAM_STR); 87 $insertStock->bindValue(':name', $_POST["name"], PDO::PARAM_INT); 88 89 // SQL文を実行する 90 $insertGoods->execute(); 91 $insertStock->execute(); 92 // トランザクション処理を完了する 93 $pdo->commit(); 94 // 結果報告 95 echo "商品データ/在庫データを追加しました。"; 96 } catch (Exception $e) { 97 // エラーがあったならば元の状態に戻す 98 $pdo->rollBack(); 99 echo '<span class="error">登録エラーがありました。</span><br>'; 100 echo $e->getMessage(); 101 } 102 ?> 103 <hr> 104 <p><a href="<?php echo $gobackURL ?>">戻る</a></p> 105</div> 106</body> 107</html> 108
- util.php
php
1<?php 2// XSS対策のためのHTMLエスケープ 3function es($data, $charset='UTF-8'){ 4 // $dataが配列のとき 5 if (is_array($data)){ 6 // 再帰呼び出し 7 return array_map(__METHOD__, $data); 8 } else { 9 // HTMLエスケープを行う 10 return htmlspecialchars($data, ENT_QUOTES, $charset); 11 } 12} 13 14// 配列の文字エンコードのチェックを行う 15function cken(array $data){ 16 $result = true; 17 foreach ($data as $key => $value) { 18 if (is_array($value)){ 19 // 含まれている値が配列のとき文字列に連結する 20 $value = implode("", $value); 21 } 22 if (!mb_check_encoding($value)){ 23 // 文字エンコードが一致しないとき 24 $result = false; 25 // foreachでの走査をブレイクする 26 break; 27 } 28 } 29 return $result; 30} 31// ?> 32
回答1件
あなたの回答
tips
プレビュー