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

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

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

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

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

Q&A

解決済

1回答

880閲覧

PHP,MySQLのエラー処理がうまく出来ない

oyatsu8

総合スコア97

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

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

0グッド

1クリップ

投稿2017/11/26 06:18

編集2017/11/27 05:28

現在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

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2017/11/26 06:26

タイトルと質問内容があっていません。トランザクションではなく、エラー処理では?
oyatsu8

2017/11/26 06:28

すみません修正します
guest

回答1

0

ベストアンサー

材料が空です。

このエラーメッセージは、$_POST["material_name"] がNULLあるいは空文字列の場合に出るものですが、入力フォームを確認すると、name="material_name" のinputがないので、このメッセージとなるのは当然のように思えます。


スクリプトを更に調べると、以下の項目が送られていないようです。

  • id_material
  • id_title
  • title_ja

投稿2017/11/26 08:02

編集2017/11/26 08:48
ockeghem

総合スコア11701

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

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

oyatsu8

2017/11/26 14:08

ありがとうございます。確認してみます。
oyatsu8

2017/11/26 17:45

まだ出来ていないのですが、一つ質問させて頂けないでしょうか、今の自分の正規化でフォームで入力をしてもらう場合は、一つ一つの項目に対してidを入力しないといけなくなってしまうのですが、そんなフォームは見た事がありません、、そのような時に普通はどうするのでしょうか
ockeghem

2017/11/26 21:46

まったく別の質問だと思うので、新しい質問として投稿下さい
oyatsu8

2017/11/27 05:28

ありがとうございます。また別で質問させて頂きます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問