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

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

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

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

PHP

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

3回答

1400閲覧

PHPでMySQLに接続してデータを追加する方法

kappaTKO

総合スコア37

MySQL

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

PHP

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2019/07/10 07:28

編集2019/07/11 06:26

HTMLの入力フォームから名前と年齢を入力します。
登録ボタンを押すとそのデータがMySQLに追加させたいです。

MySQLにデータがINSERTできません。
わからないことは、プリペアドステートメントでSQLを生成するところで
名前と年齢の2つの値をセットしたいです。

名前と年齢を固定にした
database3.php
を実行するとデータは入力できているのですが、
入力フォームから任意で入力された値を追加できません。

ご教示よろしくお願いします。

入力フォーム:database1.html

<!DOCTYPE html> <html> <head> <title>データを入力する</title> <meta charset="utf-8"> </head> <body> <?php $username=filter_input(INPUT_POST,"yourname",FILTER_VALIDATE_REGEXP,["options"=>["regexp"=>"/^.{1,10}$/"]]); $yourold=filter_input(INPUT_POST,"yourold",FILTER_VALIDATE_INT); var_dump($username,$yourold); ?> <h1>フォーム画面</h1> <form action="database2.php" method="post"> 名前を入力:<input type="text" name="yourname"> 年齢を入力:<input type="text" name="yourold"> <input type="submit" value="登録する"> </form> </body> </html>

DB操作:database2.php

<?php <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> </head> <body> <?php // エラー表示なし //ini_set('display_errors',0); // エラー表示あり ini_set('display_errors',1); header("Content-type: text/html; charset=utf-8"); // PHPのエラーを表示するように設定 error_reporting(E_ALL & ~E_NOTICE); // ポストにデータがあるかどうか if(empty($_POST)) { echo "<a href='database1.html'>database1.html</a>←こちらのページからどうぞ"; }else{ // 名前入力チェック if (isset($_POST["yourname"])) { $name=filter_input(INPUT_POST,"yourname",FILTER_VALIDATE_REGEXP,["options"=>["regexp"=>"/^.{1,10}$/"]]); } if (is_null($name)) { }else { } // 年齢入力チェック if (isset($_POST["yourold"])) { $old=filter_input(INPUT_POST,"yourold",FILTER_VALIDATE_INT); } if (is_null($old)) { }else { } //var_dump($old); try{ // DB情報 $host='localhost'; $db='db_boy'; $user='boy'; $pass='boy1234'; // インプット値 $i_user = (string)filter_input(INPUT_POST, $name); $i_pass = (string)filter_input(INPUT_POST, $old); // charsetを指定 $options = array(PDO::MYSQL_ATTR_INIT_COMMAND=>"SET CHARACTER SET 'utf8'"); // DBに接続 $pdo=new PDO("mysql: host=$host; dbname=$db", $user, $pass, $options); // PDOの属性:例外を投げる $pdo -> setAttribute( PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION); // PDOの属性:プリペアドステートメントのエミュレーションを無効 $pdo -> setAttribute( PDO :: ATTR_EMULATE_PREPARES, false); // 接続確認 if ($pdo) { //echo "データベースに接続しています" } else { echo "データベースに接続できません"; } // SQLの準備して、それを$stmt変数に定義 // 名前付きのプレースホルダにパラメータをバインドするには、 // プレースホルダの名前はコロン付きにすること $stmt = $pdo->prepare("INSERT INTO m_boy(name,old) VALUES (:name,:old)"); // トランザクション開始 $pdo->beginTransaction(); // プレースホルダへ実際の値を設定する $stmt->bindParam(':name', $name); $stmt->bindParam(':old', $old); // SQL実行 $stmt->execute(); // コミット $pdo->commit(); echo "登録完了"; // データベース切断 $stmt = null; $pdo = null; } catch (Exception $e) { $stmt->rollBack(); echo "失敗しました。" . $e->getMessage(); exit; } } ?> </body> </html>

DB操作(値は固定):database3.php

<?php $host="localhost"; $db="db_boy"; $user="boy"; $pass="boy1234"; $i_user = (string)filter_input(INPUT_POST, $name); $i_pass = (string)filter_input(INPUT_POST, $old); $d=new pdo("mysql: host=$host; dbname=$db", $user, $pass)or die("接続失敗"); $d -> setAttribute( PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION); $d -> setAttribute( PDO :: ATTR_EMULATE_PREPARES, false); print "接続成功<BR>"; $stmt = $d->prepare("insert into tb values('test6','60')"); $stmt->bindValue(1, $i_user); $stmt->bindValue(2, $i_pass); $stmt->execute(); ?>

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

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

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

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

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

yukikp

2019/07/10 10:24 編集

//プリペアドステートメント $stmt = $mysqli->prepare("INSERT INTO db_boy (name,old) VALUES (?,?)"); $i_name = (string)filter_input(INPUT_POST, $name); //<= $name ではなくて、'yourname' $i_old = (string)filter_input(INPUT_POST, $old); //<= $old ではなくて、'yourold' $stmt->bindValue(1, $i_name); // escapeさせていた意味がよく分からない $stmt->bindValue(2, $i_old); // escapeさせていた意味がよく分からない if($stmt->execute()){ //略
yukikp

2019/07/10 10:26

//プレースホルダへ実際の値を設定する $stmt->bind_param('1', $yourname); $stmt->bind_param('2', $yourold); $yourname = $_POST['yourname']; &yourold = $_POST['yourold'] ↑これ全部いらない。
yukikp

2019/07/10 10:31

流れとしては、 (1)データベースに接続 (2)接続で来たらPOSTデータを filter_input( INPUT_POST, 'hogehoge', 【フィルター】);で受け取る。 ※フィルターについては、https://b-estack.com/2018/10/24/useful_filter_input/みたいなのを呼んで必要なものを使う (3)$mysqli->prepareでプリペアードステートメントの準備 (4)bindValueを使って、置き換えの設定をする (5)execute()を使って実行 をすればいいだけです。 ※もちろんバリデーションや、エラーの際の処理なんかも必要ですが。 ですがdatabase2.phpを見ていると、余計な変数にPOSTデータ入れたり、プリペアードステートメントができてないのにbindValueさせたりしていますよね。 そこらへんを整理するとたぶん自分でもわかりやすく書けると思いますよ~
guest

回答3

0

database2.php

  • PDOが2度呼び出されているので無駄になっていると思います。
  • mysqli_*が呼ばれていますが、どちらかに統一したほうが良いですし、今回はPDO一本で良いでしょう。
  • 変数未定義のまま使っています。

php

1 $stmt->bind_param('1', $yourname); 2 $stmt->bind_param('2', $yourold); 3 $yourname = $_POST['yourname']; 4 &yourold = $_POST['yourold']
  • ↑そして使った後に定義していますし、片方&youroldとなっていてそもそも変数になっていません。
  • 上記だけでなく「変数を使った後に定義」が散見されます。「変数を定義した後に使う」流れを徹底してください
  • try-catchは接続時だけでなくDB処理一連全て囲っておいてください。
  • DBに変更を与える処理なのでできればトランザクション→コミットorロールバックは入れておいたほうが良いです(参考:PHPマニュアル:トランザクションおよび自動コミット)

はじめのうちはPHPのエラー表示はONにしておいたほうが良いでしょう。

database3.php

パラメータがないINSERT文なのでbindValue使ってません。

投稿2019/07/10 07:31

編集2019/07/10 07:39
m.ts10806

総合スコア80850

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

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

kappaTKO

2019/07/10 11:01

mts10806さん、お返事ありがとうございます。 一回整理してみました。
guest

0

たとえば最低限こういうバリデートをいれる

PHP

1<?PHP 2$username=filter_input(INPUT_POST,"yourname",FILTER_VALIDATE_REGEXP,["options"=>["regexp"=>"/^.{1,10}$/"]]); 3$yourold=filter_input(INPUT_POST,"yourold",FILTER_VALIDATE_INT); 4var_dump($username,$yourold); 5?> 6 7<h1>フォーム画面</h1> 8<form method="post"> 9名前を入力:<input type="text" name="yourname"><br> 10年齢を入力:<input type="text" name="yourold"><br> 11<input type="submit" value="登録する"> 12</form>

文字列の場合は禁止文字の指定など適当に
数値は最低値や最高値の設定ができる

その上で
is_null($username)でパラメータが送られてきているかどうかでチェック
$username!==falseでバリデートに失敗していないかチェック

投稿2019/07/10 08:24

yambejp

総合スコア114769

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

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

kappaTKO

2019/07/10 11:02

yambejpさん、お返事ありがとうございます。 コードそのまま追記させていただきました。
yukikp

2019/07/10 11:13

yambejpさんは、 $name = $_POST['name']; 見たいなPOSTデータの受け取り方は【やっちゃダメ】という意味で上記コードを書いたので、database1.htmlに追記するのではなくて database2.phpの $name = $_POST['yourname']; $old = $_POST['yourold']; を書き直した方が良いよと言っています。(言ってないけど、そういう意味合いです) んで、何かうまく行かなくなったら、var_dump();で受け取った変数の中身をチェックしてみるといいよという事です。
kappaTKO

2019/07/11 03:56

データの入力判定が難しいです。 1.ポストデータについて 名前と年齢を入力せずに登録ボンタンをクリックしても、ポストデータが入力されていると判断されてしまいます。なぜでしょうか? 2.$nameについて filter_inputを使用して$nameに代入しているのですが、Nullと判定されません。 名前と年齢が入力されていないときはチェックをかけたいです。 echo "1"; // ポストにデータがあるかどうか if(empty($_POST)) { echo "2"; }else{ // 名前入力チェック if (isset($_POST["yourname"])) { $name=filter_input(INPUT_POST,"yourname",FILTER_VALIDATE_REGEXP,["options"=>["regexp"=>"/^.{1,10}$/"]]); echo $name; } if (is_null($name)) { echo "3"; }else { echo "4"; } }
hideki_nakajima

2019/07/11 04:06

名前を入力:<input type="text" name="yourname" required> 年齢を入力:<input type="number" name="yourold" required> required属性を指定してください。年齢のtype属性でnumberを指定すると、数字以外は入力できなくなるので、これも便利です。
kappaTKO

2019/07/11 06:20

ありがとうございます。 属性を変更してみます。
guest

0

ベストアンサー

php

1// トランザクション開始 2$stmt->beginTransaction(); 3 4// コミット 5$stmt->commit();

これらのメソッドはPDOStatementではなくPDOクラスの物ですので、こう書くのが正しいはずです。

php

1// トランザクション開始 2$pdo->beginTransaction(); 3 4// コミット 5$pdo->commit();

php

1// SQLの準備して、それを$stmt変数に定義 2$stmt = $pdo->prepare("INSERT INTO m_boy(name,old) VALUES (?,?)"); 3 4// プレースホルダへ実際の値を設定する 5$stmt->bindParam('name', $name); 6$stmt->bindParam('old', $old); 7 8// SQL実行 9$stmt->execute(array($name, $old));

PDOStatement::bindParam()で名前付きのプレースホルダにパラメータをバインドするには、プレースホルダの名前は:hogeのようにコロン付きである必要があります。

php

1// SQLの準備して、それを$stmt変数に定義 2$stmt = $pdo->prepare("INSERT INTO m_boy(name,old) VALUES (:name,:old)"); 3 4// プレースホルダへ実際の値を設定する 5$stmt->bindParam(':name', $name); 6$stmt->bindParam(':old', $old); 7 8// SQL実行 9$stmt->execute(); /* 既に値がバインドされているため、ここに引数を入れる必要はありません */

上手く行かなかった場合

これでも上手く行かなかった場合、失敗しました。の後にエラーメッセージが吐かれているはずです。それをよく読んでください(または、ここに貼ってください)。
それと、「値が固定されていれば上手くいくはず」という比較のために書かれたdatabase3.phpですが、比較対象のdatabase2.phpとなるべく同じSQL式を書いた方が良い比較になるんじゃないでしょうか。
例: INSERT INTO m_boy(name,old) VALUES ('test6','60')
これが上手く行くなら本当にdatabase2.phpのプログラムに問題があることになりますし、これでエラーが起こるならSQL式が間違っているのだと思われます。

投稿2019/07/11 02:12

hideki_nakajima

総合スコア44

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

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

kappaTKO

2019/07/11 06:24

hideki_nakajimaさん、お返事ありがとうございます。 データベースにデータを入力することができました。 次は入力するデータがデータベースに存在するかどうか確認してからデータを挿入する処理を作成したいとおもいます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問