🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
INSERT

INSERTとは、行を追加する、コンピュータのデータベース言語SQLにおけるデータ操作言語(DML)ステートメントの1つである

MySQL

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

PHP

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

Q&A

解決済

2回答

3665閲覧

簡易掲示板・MySQLでINSERTして投稿したいが、エラーがどうしてもわかりません。

MakotoIshizawa

総合スコア32

INSERT

INSERTとは、行を追加する、コンピュータのデータベース言語SQLにおけるデータ操作言語(DML)ステートメントの1つである

MySQL

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

PHP

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

0グッド

0クリップ

投稿2019/12/13 02:17

編集2019/12/13 21:46

###前提
簡易掲示板の課題に取り組んでいます。
テキスト保存のものを作成した後、MySQL保存のものを作成しています。
PHP5.2.4(指定による)
外部のMySQLで設定によりコマンドによる操作はできません。
##本題
前回のアドバイスに従い、投稿機能だけ取り出し作成してみたところです。
https://teratail.com/questions/227810
POSTされた値の格納された変数をバインドした形で書き直し、ヒアドキュメント構文に直しました。
何故か、SQL文がおかしくて投稿できません。
教えていただいた構文チェツクサイトでみたところ、
insertのSQL文の:name, :comment, now(), :passwordの行がエラーになりました。
何が行けないのでしょうか?

以下はエラー文です。
you have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near':name, :comment, now(), :password
)'at line 4

試したことを追記です。
他のファイルで投稿機能、削除機能、編集機能まで書いたものがあります。
そこでは同じコードがうまく動作しました。
それをコピペしましたが、投稿機能だけ取り出した方ではうまくいきませんでした。
そしてそれを構文チェックのサイトにコピペすると同じエラーが出てきます。

サーバー情報は伏せてあります。
###その後試したこと
進展がありましたので追記します。
どうやらSQL文のせいではなかったようです。
$name,$comment,$passwordをvar_dumpしたところ、$nameだけが空になっていました。
フォームに問題がありそうですが、まだ見つかりません。
変数の定義、投稿のコード、投稿フォームの$nameの関係するところをもう少し丁寧に見てみます。

道理でブラウザにはエラーが表示されなかったわけですね。
構文チェックサイトでエラーになったので勘違いしドツボにはまってしまいました。
大変お騒がせしました。
もっと慎重に順序立てて考えていかないといけないですね。
反省します。

PHP

1<?php 2ini_set( "display_errors", 1 ); 3error_reporting( E_ALL ); 4//MySQL接続情報 5$servername = ""; 6$username = ""; 7$serverpassword = ""; 8$dbname = ""; 9//データベースに接続 10try { 11 $db = new PDO( 12 "mysql:dbname=$dbname;host=$servername;charset=utf8mb4", $username, $serverpassword, [ 13 PDO::ATTR_ERRMODE =>PDO::ERRMODE_EXCEPTION, 14 PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, 15 ] ); 16} catch ( PDOException $e ) { 17 print( "接続エラー:". $e->getMessage() ); 18 die(); 19} 20//投稿フォームの変数定義 21$name = (string)filter_input( INPUT_POST, "name" );//post送信された投稿者の名前 22$comment = (string)filter_input( INPUT_POST, "comment");//post送信された投稿コメント 23$password = (int)filter_input( INPUT_POST, "password" );//post送信された投稿パスワード 24//投稿機能 25try{ 26 if ( !empty( $name ) && !empty( $comment ) && !empty( $password ) ){ 27 $sql = <<<EOT 28 INSERT INTO toko( 29 name, comment, date, password 30 ) VALUES ( 31 :name, :comment, now(), :password 32 ) 33EOT; 34 $stmt = $db -> prepare( $sql ); 35 $stmt -> bindvalue( ':name', $name, PDO::PARAM_STR ); 36 $stmt -> bindvalue( ':comment', $comment, PDO::PARAM_STR ); 37 $stmt -> bindvalue( ':password', $password, PDO::PARAM_INT ); 38 $stmt -> execute(); 39 } 40} catch ( PDOException $e ) { 41 print( "投稿エラー:". $e->getMessage() ); 42 die(); 43} 44 45?> 46<!doctype html> 47 48<html lang="ja"> 49<head> 50<meta charset="utf-8"> 51<title>投稿フォームMySQL版</title> 52<style> 53 .akaji{ 54 color : red ; 55 } 56 .komoji{ 57 font-size : 0.8em; 58 } 59</style> 60</head> 61 62<body> 63 <!--投稿フォーム--> 64  <form method="post"> 65 <label for="name">お名前<span class="akaji">【必須】</span></label><br> 66  <input type="text" name="name" id="name" required><br> 67 <label for="comment">コメント<span class="akaji">【必須】</span></label><br> 68 <textarea name="comment" cols="30" rows="3" id="comment" required></textarea><br> 69 <label for="password">パスワード<span class="akaji">【必須】</span></label><br> 70 <input type="password" name="password" id="password" required><br> 71 <input type="submit" value="送信"> 72  </form> 73 <br> 74 <!--投稿一覧表示--> 75<?php 76//投稿内容の表示 77 //XSS対策 78 function h( $str ) { 79 return nl2br( htmlspecialchars( $str,ENT_QUOTES, 'UTF-8' ) ); 80 } 81 try{ 82 //行数の取得 83 $sql = 'SELECT COUNT(*) FROM toko'; 84 $count = $db -> query( $sql ); 85 $count = $count -> fetchColumn(); 86 var_dump( $count ); 87 if ( $count == 0 ) {//行数が0だったら 88 echo "<p>投稿はまだありません</p>";//投稿はまだありませんと表示する 89 } else {//それ以外の場合は 90 $sql = 'SELECT * FROM toko';//テーブルデータの取得のクエリ 91 $select = $db -> query( $sql );//クエリ実行 92 foreach ( $select as $row ) {//ループ 93 echo "<span class='komoji'>No</span>:" . h( $row[ 'num' ] ) . "&emsp;&emsp;";//番号の表示 94 echo "<span class='komoji'>名前</span>:" . h( $row[ 'name' ] ) . "<br>";//名前の表示 95 echo h( $row[ 'comment' ] ) . "<br>" ;//コメントの表示 96 echo "<span class='komoji'>" . h( $row[ 'date' ] ) . "</span><br>";//日時の表示 97 } 98 } 99 } catch ( PDOException $e ) { 100 print( "表示エラー:" . $e->getMessage() ); 101 die(); 102 } 103?> 104</body> 105</html>

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

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

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

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

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

H40831

2019/12/13 02:27

エラー文は読みましたか? エラー原因を解明するにはエラー文を読むことが必須です。 それが理解できていれば、質問文にエラー文を載せないという謎行動を起こされることはないかと思うので、 エラー文をまず読んで、それでもわからなければ質問文に追記をしてください。
MakotoIshizawa

2019/12/13 02:39

すみません。追記します。 エラー文で検索しました。 構文エラーのはずなんですが 何度も間違いがないか丹念に探したつもりなんですが見つかりません。
m.ts10806

2019/12/13 02:53

bindValueで というアドバイスを受けてなぜbindparam を使っているのでしょうか。 SQLのエラーのようですが、PHP介さず直接DBに固定値入れてコマンド実行で確かめてみましたか?
MakotoIshizawa

2019/12/13 03:04

バインドについて検索しましたところbindparamが変数のみということだったので、こちらにしてみました。baindvalueも変数が扱えることは読みましたが、なんとなく変数専用ぽい感じがしてこちらを使ってしまいました。 外部のMySQLなので直接扱えない状態なんですが、自分のPCでもインストールしてやってみます。
date

2019/12/13 03:31

INSERT INTO toko( name, comment, date, password ) VALUES ( :name, :comment, now(), :password ) たぶんこれをそのままMySQLの構文チェックサイトでチェックしたと思いますが、これはphpでの書き方なのでmysqlの構文チェックサイトでチェックしたら提示のエラーになります。
m.ts10806

2019/12/13 03:57

私「固定値入れてコマンド実行で」と書いてます。bindValueの件といい、アドバイスをとことん聞かない人ですね…。 思い込みでプログラムは動きませんよ。書いた通りに動くだけです。
MakotoIshizawa

2019/12/13 18:51

すみません。このDBは外部のもので直接コマンドではアクセスできない状態なのです。 質問文に書いておくべきでしたね。 bindvalueは直そうと思います。
MakotoIshizawa

2019/12/13 18:53

構文チェックサイトについて御指摘ありがとうございます。 助かりました。
guest

回答2

0

ざっくり見た感じはとくに問題なさそうですが
エラーを見る限りSQL文に見えないゴミがはいっている可能性もあるかもしれません

とりあえずvaluesの後ろに改行もなにも入れないで試してみてください

PHP

1 $sql = <<<EOT 2 INSERT INTO toko( 3 name, comment, date, password 4 ) VALUES (:name, :comment, now(), :password) 5EOT; 6 $stmt = $db -> prepare( $sql ); 7 $stmt -> bindparam( ':name', $name, PDO::PARAM_STR ); 8 $stmt -> bindparam( ':comment', $comment, PDO::PARAM_STR ); 9 $stmt -> bindparam( ':password', $password, PDO::PARAM_INT ); 10 $stmt -> execute();

改善しない場合は、とりあえずラベルではなく疑問符でためしてください

PHP

1 $sql = <<<EOT 2 INSERT INTO toko( 3 name, comment, date, password 4 ) VALUES (?,?,now(),?) 5EOT; 6 $stmt = $db -> prepare( $sql ); 7); 8 $stmt -> execute([$name,$commen,$password]);

投稿2019/12/13 03:17

yambejp

総合スコア116694

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

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

MakotoIshizawa

2019/12/13 03:22

ありがとうございます。 今日はもう寝なきゃいけないので、早朝試してみます。
退会済みユーザー

退会済みユーザー

2019/12/13 03:44

bindParamじゃなくbindValueなんじゃね? 知らんけど
yambejp

2019/12/13 03:50

bindParamは変数で指定する制限はあるけど 後からでも値を変更できる仕様なので 今回のようにbindParamより前で変数が確定している場合 bindParamでもbindValueでもどちらでも問題ないです
退会済みユーザー

退会済みユーザー

2019/12/13 04:28

じゃぁ、このphpファイルがCR-LFな改行コードだったりするとか。 そうなら、LFのみにするなど試す。
yambejp

2019/12/13 04:32

SQL文は原則改行マークを無視する(空白文字の一つとして認識)ので 微妙ですがせっかくなので懸念点があれば別途回答してあげては?
MakotoIshizawa

2019/12/13 19:08

bindparamを軽々しく使ってしまいましたが、ちゃんと理解していないので元のアドバイスに従いbindvalueに直しました。 後で、マニュアルを熟読したいと思います。
MakotoIshizawa

2019/12/14 00:43

以下にbindparamについて注意書きを見つけました。 https://qiita.com/mpyw/items/b00b72c5c95aac573b71 PDOStatement::bindParam メソッドもありますが,原則的にこちらを使う必要はありません.エミュレーションがONの場合,実行後にバインドした変数が文字列型にされる仕様もあるので注意してください.
guest

0

自己解決

#皆様大変お騒がせしまして申し訳ありませんでした。
##結論
formのinputの要素中に全角スペースがあり、nameが送信されませんでした。
そのため、if文で$nameと$commentと$passwordに!emptyを条件にしていたinsertが作動しなかったという現象でした。
全角スペースを半角に治すことで正しく動作しました。
insert文は最初のもので大丈夫でした。

浅はかな考えと軽率な行動による勘違いでお騒がせしました。

投稿2019/12/13 21:42

編集2019/12/13 22:02
MakotoIshizawa

総合スコア32

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問