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

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

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

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

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

Q&A

4回答

1530閲覧

PHPファイルからINSERT(SQL文)を実行しても追加されない

yamayama3965

総合スコア11

phpMyAdmin

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

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

0グッド

1クリップ

投稿2019/07/07 06:20

編集2019/07/07 08:48

前提・実現したいこと

現在PHPの勉強中で簡単な家計簿を作成しています。
DBへのINSERT文がうまくいっていないようです。
日付を取得してはいるが、それが入らないためにうまくいっていないのかと・・・

発生している問題・エラーメッセージ

PHPのファイルからDBへINSERTしても追加されません。
DBとの接続ができているかSELECT文を実行したところ、(40〜46行目)
予めテストとして入れておいた内容は取得できました。

エラーメッセージ等は発生しておらず、
処理が完了した際は処理完了後のメッセージが表示されます。

該当のソースコード

PHP

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <title>家計簿登録</title> 6</head> 7<body> 8 9<p>家計簿</p> 10 11<h2>支出の登録</h2> 12<form action="" method="post" enctype="multipart/form-data"> 13 <select name="category"> 14 <?php 15 $category = [ 16 "食費", 17 "雑費", 18 "生活費", 19 "あそび" 20 ]; 21 foreach($category as $item){ 22 echo '<option value ="'.$item.'">'.$item.'</option>'; 23 } 24 ?> 25 </select> 26<input type="text" name="name"><br> 27<input type="text" name="price"><br> 28<input type="submit" value="登録する" name="send"> 29 30</form> 31 32</body> 33</html> 34 35<!-- DBに追加 --> 36<?php 37$pdo = new PDO('mysql:host=localhost; dbname=moneynote; charset=utf8', 'root', ''); 38 39 40// foreach($pdo->query('SELECT * FROM `record` WHERE `no` = 3') as $row){ 41// echo $row['no']; 42// echo $row['day']; 43// echo $row['category']; 44// echo $row['name']; 45// echo $row['price']; 46// } 47 48 49if(isset($_POST['send'])){ 50 $day = date("Y-m-d"); 51 $category = $_POST['category']; 52 $name = $_POST['name']; 53 $price = $_POST['price']; 54 $sql = 'INSERT INTO `record`(`no`, `day`, `category`, `name`, `price`) VALUES (NULL, cast($day as data), $category, $name, $price);'; 55 $pdo->query($sql); 56 echo "追加しました"; 57} 58 59var_dump($day); 60 61 62 63?> 64<!-- DBに追加 ここまで -->

試したこと

SQL文の変数に値を直接入れて、phpmyadminから直接SQL文を実行すると内容は追加されました。

補足情報(FW/ツールのバージョンなど)

環境はmacでlammpを使用しています。
localhost:8080で表示しており、DBはphpmyadminを使用しています。

SQLの構造は以下の通りです。
テーブル:record

|名前|データ型|照合順序|NULL|デフォルト値|その他|
|:--|:--:|--:|
|no|int(4)||いいえ|なし|AUTO_INCREMENT|
|day|date||いいえ|なし||
|category|varchar(20)||いいえ|なし||
|name|varchar(20)||いいえ|なし||
|price|int(5)||いいえ|なし||

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

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

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

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

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

m.ts10806

2019/07/07 08:43

タイトルは質問内容に寄せた要件(起きている問題など)を記載してください。
guest

回答4

0

シングルクォーテーション内では変数は展開されません。
またSQLに文字列を投入する場合、'で囲う必要があります。
ただ、このままですと入力情報をそのまま投入しているのでSQLインジェクションの脆弱性があります。
パラメーターでSQLセット(prepare)→値のセット(bindValue)→実行(execute)の流れにされたほうが良いでしょう。
また、try-catchでPDOExceptionを拾う作りも入れましょう。

もろもろ含めて下記のような記事は読んで実装に活かしましょう。
PHPでデータベースに接続するときのまとめ

投稿2019/07/07 08:50

編集2019/07/07 08:57
m.ts10806

総合スコア80850

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

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

yamayama3965

2019/07/07 10:03

prepareやexecuteは自分的にはもう一段階上のレベルかと思い、簡単にまず作れるかを試していました・・・。わからない言葉があるので調べつつ実践してみます。
m.ts10806

2019/07/07 11:13

そもそもはシングルクォーテーション内に変数を書いていること、文字列をSQL内で'で囲わずに書いていることです。 いずれにしても、あまり生でSQL実行する記述はないので(現場ではフレームワークですし) このさいPDOは覚えて見ましょう。 提示したようにしっかりと書かれている文献も多いので使い方の理解には繋がりやすいと思います
yamayama3965

2019/07/07 12:55

シングルクォーテーション外に変数を持ってくるとなると.で連結する必要があるということでしょうか? また、NULLの時も'はいるのですか?見当違いな内容でしたらすみません・・・。
m.ts10806

2019/07/07 20:08

PHPで実行する前にDBに対して実行して想定通りの結果を得られるか確かめてみてください。 DBはPHPからすると外部の概念であるため、直接実行して成功しなければもちろんPHPから実行しても動きません。 SQLとはいってもPHPからすると単なる文字列の集合体に過ぎませんので、通常文字列を扱うときと同じように組む必要があります。 echoで$sqlを出力してでてきた文字列がどのようなものか確かめて、それがDBに対して直接実行して成功するか確認するところからですね。
yamayama3965

2019/07/08 12:49

echo で出力した$sqlをDBに対して直接実行するとエラーが出ましたが、$categoryと$nameに入る文字列をダブルクォーテーションで囲めば成功しました。 PHPでSQL文を実行する場合変数にダブルクォーテーションは使えないと思うのですが・・・やはりこれが原因でしょうか。
m.ts10806

2019/07/23 01:11

返信気づきませんでした。すみません。 > echo で出力した$sqlをDBに対して直接実行するとエラーが出ましたが、$categoryと$nameに入る文字列をダブルクォーテーションで囲めば成功しました。 ダブルクォーテーションではSQL的には値は文字列としては解釈されないと思います。 >PHPでSQL文を実行する場合変数にダブルクォーテーションは使えないと思うのですが ちょっと意味が分からないです。PHPの変数とはあくまで文字列であって、SQLもその文字列の一端ですよ。
guest

0

$sql=のとこの最後 $price);'; この部分、もしこのまま書かれているなら )の次の;がシンタックスエラーではありますね。チェックしてみて書いてあるなら削除してください。

投稿2019/07/07 12:09

mari.rinn

総合スコア296

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

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

yamayama3965

2019/07/07 12:50

SQL文は最後に;がいると思うので一つ目の;はSQL文の終わり、二つ目の;は変数に代入の終わりを示しているのですがこの場合いらないのでしょうか?
mari.rinn

2019/07/07 20:49

少し勘違いされているのではないかと思いますよ。;は何文の最後だからとかではなく、その処理の最後(はい、これはここまでね みたいな意味)を表すものなので、この場合は変数にクォーテーションで囲まれたものを代入するという処理の最後に一つだけ入れる形となります。
m.ts10806

2019/07/08 00:25 編集

mari.rinnさん 動かしてみればわかりますが、シンタックスエラーじゃないですよ。 yamayama3965さんの仰っている通り、SQLの;とPHPの;で文末として意味合いが別のものです。
mari.rinn

2019/07/08 00:34

ええ?そうなんですか〜?私の方が勘違いでしたか〜! それは大変失礼いたしました〜! 質問者様、ごめんなさい!! 皆様もお目汚し失礼しました。
guest

0

下記のような形でSQLのエラー情報を確認してみて下さい。

php

1$statement = $pdo->query($sql); 2 3print_r($statement->errorInfo());

投稿2019/07/07 10:08

dany

総合スコア73

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

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

yamayama3965

2019/07/07 12:49

Fatal error: Uncaught Error: Call to a member function errorInfo() on boolean 上記のメッセージが表示されました。 これって型が違うから入らないってことでしょうか?
dany

2019/07/07 13:25 編集

SQLの実行結果でfalseが帰ってきているようなので、やはりエラーが出ていると思います。下記でエラー内容を確認してみて下さい。 $pdo->query($sql); print_r($pdo->errorInfo());
dany

2019/07/07 13:30

気になることがあと2点ほどあります。他の方も指摘しているシングルクオートの問題です。 $sql = 'INSERT INTO `record`(`no`, `day`, `category`, `name`, `price`) VALUES (NULL, cast($day as data), $category, $name, $price);'; を $sql = "INSERT INTO `record`(`no`, `day`, `category`, `name`, `price`) VALUES (NULL, cast($day as data), $category, $name, $price);"; に変更。 あと、cast($day as data)は cast($day as date)の間違いでしょうか? ちなみに、この場合はキャストしなくても大丈夫だと思います。
yamayama3965

2019/07/08 12:42

ご指摘いただいたSQL文に変更し、エラー確認文を追記しました。 Array ( [0] => 42S22 [1] => 1054 [2] => Unknown column '食費' in 'field list' ) 追加しました 上記の内容が表示されました。 また、cast($day as data)はcast($day as date)の間違いです・・・。 初歩的なミスですみません・・・。
guest

0

最後に commit をしたら正常に insert されますでしょうか。
https://www.php.net/manual/ja/pdo.commit.php

直接 SQL を実行した場合、オートコミットのため正常に insert されているのかと思います。

ご参考ください。

投稿2019/07/07 06:39

shaw

総合スコア209

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

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

yamayama3965

2019/07/07 06:47

INSERT分実行の後に「$pdo->commit();」を追記したところ、以下のエラーが生じました。 Fatal error: Uncaught PDOException: There is no active transaction in /opt/lampp/htdocs/moneynote/money.php:56 Stack trace: #0 /opt/lampp/htdocs/moneynote/money.php(56): PDO->commit() #1 {main} thrown in /opt/lampp/htdocs/moneynote/money.php on line 56 また、DBにもデータは追加されませんでした。
m.ts10806

2019/07/07 08:44

トランザクション張ってないとコミットは意味ないですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問