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

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

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

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

Q&A

解決済

4回答

384閲覧

PHP PDOを使用する

tanukitii

総合スコア44

PHP

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

0グッド

0クリップ

投稿2018/10/19 13:03

編集2018/10/20 08:13

PHPでMySQL付近の勉強をしようと思いました。PDOクラスを使おうと思い,コードを書いてみたのですが,うまくいかない部分があり,詰まってしまいました。

php

1<?php 2try{ 3 $db = new PDO('mysql:dbname = mydb; host = 127.0.0.1; charset = utf8', '△△△', '〇〇〇'); 4}catch(PDOException $e){ 5 echo "DB接続エラー:". $e->getMessage(); 6} 7 8 $count = $db->exec('INSERT INTO my_items SET maker_id=1, item_name="もも", price=210, keyword="缶詰,ピンク,甘い", sales=0'); 9 echo $count . '件のデータを挿入しました。'; 10?>

出力結果は
件のデータを挿入しました。

で,countの値が表示されません。本来なら入力したSQL文の数ぶん(今回は1)が返ると思うのですが,何も表示されないのです。
いろいろ調べてはみたのですが,PHPのverが7以上であればphp.iniをいじらなくてもPDOは使えますし,コードの間違いも特に見当たらなくどうしたものかと悩んでおります。
ご助言いただけると幸いです。

【追記】
下記のようにコードを修正しても現状は変わらずです。

php

1<?php 2try{ 3 $db = new PDO('mysql:dbname = mydb; host = 127.0.0.1; charset = utf8', '△△', '〇〇'); 4 $count = $db -> prepare('INSERT INTO my_items SET maker_id=1, item_name="モモ", price=210, keyword="缶詰,ピンク,甘い", sales=0'); 5 $count -> execute(); 6}catch(PDOException $e){ 7 echo "DB接続エラー:". $e->getMessage(); 8} 9?>

・host=localhostにしても何も変わらず。

・phpを実行している手順は上記のコードを
C:\xampp/\htdocs/memo下におき,検索エンジン(chrome)で
http://localhost/memo/index.phpと入力しています。

・php 7.2.11,phpMyAdmin 4.8.3,Apache 2.4.35をWindows10 64bitで使用しています。

・エディタはVSコードを使用しています。

・DBに入力したcreate分は

SQL

1INSERT INTO my_items SET maker_id=1, item_name="リンゴ", price=210, keyword="缶詰,ピンク,甘い", sales=0

です。これはDB上で実行するとDB上にデータが追加されます。

以上でございます。何卒よろしくお願いします。

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

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

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

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

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

guest

回答4

0

ベストアンサー

false チェックをするのが普通
false チェックをしなくてもいいようにエラーモードを変更するのが普通

PHPでデータベースに接続するときのまとめ - Qiita

ツッコミどころ多すぎるので修正後のコードだけ書いておきます。

php

1<?php 2 3try { 4 5 $pdo = new PDO( 6 'mysql:dbname=mydb;host=127.0.0.1;charset=utf8mb4', 7 '△△', 8 '〇〇', 9 [ 10 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, 11 ] 12 ); 13 14 $stmt = $pdo->prepare('INSERT INTO my_items(maker_id, item_name, price, keyword, sales) VALUES (?, ?, ?, ?, ?)'); 15 $stmt->execute([1, 'リンゴ', 210, '缶詰,ピンク,甘い', 0]); 16 17 $count = $stmt->rowCount(); 18 var_dump($count); 19 20} catch (PDOException $e) { 21 22 echo $e->getMessage(); 23 24}

投稿2018/10/20 08:50

編集2018/10/20 08:51
mpyw

総合スコア5223

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

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

tanukitii

2018/10/20 09:56

ありがとうございます。上記のコードでできました。 PDOの4つ目の引数は別になくてもDBにデータを追加できたのでSQL文が原因ということになりますよね?以前,書籍で学んだとおりにSQL文を書いて,そのときはうまくいっていたのですが,書き方がかわったのでしょうか…マニュアルにそれらしきものが見つからないですし… その多すぎるつっこみどころが何かを教えていただければうれしいのですが…。 申し訳ないです。何卒よろしくお願いします。
mpyw

2018/10/20 10:49

``` <?php try{ $db = new PDO('mysql:dbname = mydb; host = 127.0.0.1; charset = utf8', '△△', '〇〇'); $count = $db -> prepare('INSERT INTO my_items SET maker_id=1, item_name="モモ", price=210, keyword="缶詰,ピンク,甘い", sales=0'); $count -> execute(); }catch(PDOException $e){ echo "DB接続エラー:". $e->getMessage(); } ?> ``` 上記のコードに関してもっとも致命的な場所は ・PDOの第1引数のDSNは、=の前後にスペースを入れてはならない これですね。これのせいで接続の段階で失敗しているはずです。PDOException 飛んでませんかね?接続に関するエラーに関してはエラーモード変更しなくても飛ぶはずなんですが。そのほか、動作に支障は無いが直したほうがいい点を挙げると ・MySQL を使う場合は utf8 ではなく utf8mb4 を基本的に選ぶべき ・エラーモードは PDO::ERRMODE_EXCEPTION に設定しておくべき ・INSERT...SET... はMySQLの独自構文なのでできればSQL標準の INSERT...VALUES... を使うべき ・prepare する際には、文字列などの具体値は直接書かずに「?」で入れておいて、execute や bindValue で渡すべき ・prepare の返り値の変数名として $count はおかしい。整数ではなく PDOStatement オブジェクト ・PHP閉じタグの「?>」は省略できる場合は省略推奨 など
tanukitii

2018/10/20 11:01

知らないことばかりでした…。こんなにも短いコードにこれだけの問題点があるのですね。 とても勉強になりました。 多くの方から,ご助言をいただきましたが,”問題が解決した”,”私のコードの問題点を多くあげていただいた”という理由でmpywさんをベストアンサーにいたします。 誠にありがとうございます。
guest

0

2点ご確認を。

  1. そのSQL本当に実行できてる?DBに直接実行して想定通りの結果になるか?

また、プログラムから利用した場合、今回はINSERTなので利用後にDBを確認して想定通りのデータが追加されているか
コードに間違いがなくても正しくSQLが実行されないと想定通りの結果は得られませんよね。SQLもPHPからしたら外部の機能ですが「コード」です。
0. try-catchで接続だけ監視しても意味がないのでは。
SQLが正しく実行できるかどうかはPHP側は知らないので「確実に正しい結果が返ってくる」という保証はどこにもないはずです。
せっかくPDOException を捕捉しているのですから接続→実行→結果まで全て入れてあげましょう。そうしたら何かエラーを捉えてくれるかもしれません。
でも現状の書き方だとexec()における異常を検知できません。

本来なら入力したSQL文の数ぶん(今回は1)が返ると思うのですが,

「思う」は大変危険な考え方です。
プログラムは指示したとおりにしか動きません。0か1かの世界です(成功か失敗か)
「想定通りに動いていない」ということは、制作者がその指示を失敗しているにすぎません。

こういうときはデバッグです。
変数 をvar_dump()で出力してみてください。なぜ画面上に何も表示されないのかが見えてくるかと思います。

また、exec()のPHPマニュアルには下記のようにあります。

PDO::exec() は、発行した SQL ステートメントによって更新もしくは 削除された行数を返します。 1 行も作用しなかった場合、PDO::exec() は 0 を返します。

警告
この関数は論理値 FALSE を返す可能性がありますが、FALSE として評価される値を返す可能性もあります。 詳細については 論理値の セクションを参照してください。この関数の返り値を調べるには ===演算子 を 使用してください。

ここで「入力したSQL文の数ぶん(今回は1)」という理解が間違っていることがわかるかと思います。
入力したSQLの数ではなく「更新が作用した件数」です。
insertでも1文で複数レコード挿入することができます。

sql

1insert into tableA values (1,'test1'),(2,'test2'),(1,'test3')

上記は「1文」ですが、exec()にて成功した場合「3」が返る内容です。

また「警告」のところも読むとわかりますが、必ずしも作用した件数が返るわけではありません。
その辺りは、既に回答に出ている通り、正誤判定を入れた上で利用するのが確実です。

投稿2018/10/19 19:54

m.ts10806

総合スコア80765

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

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

退会済みユーザー

退会済みユーザー

2018/10/19 23:14

exec を try-catch に入れるのが良いですね。 try-catch に入れたら、正誤判定(?)いるかなぁ?INSERT INTO だし、冗長な気がする。
m.ts10806

2018/10/19 23:29

try-catchに引っかからなくて誤に入るケースが私も思い浮かばなかったですが、 PDOで接続しているなら拾えそうですね。確かに冗長かもしれません。補足ありがとうございます。
tanukitii

2018/10/20 00:20

ご回答ありがとうございます。 PHPのマニュアルは見ていたのですが,理解できていない部分があったようです。反省しております。 上記の件ですが, 1.コードを実行して,INSERT INTOで追加しようとしたデータは,データベース内には存在しませんでした。SQL文が実行されていないということは分かっていたのですが,それがコードの問題なのかphp.iniなどをいじらなければいけない問題なのか分かりませんでした。 2.おっしゃる通りです。改善していきます。 var_dump($count);と実行してみたところ,falseが返ってきました。 ということはSQL文が間違っているということでしょうか?? 申し訳ございません。よろしくお願いいたします。
m.ts10806

2018/10/20 00:25

1.の冒頭に書いてある通り、そのSQLを直接DBログインして実行してみてください。 XAMPPなど入れたのであればphpmyadminが入っているのでそこから。 try-catchにINSERT実行も入れることでPDOExceptionで何かしらエラーを捕捉できるかもしれないので、 そちらの対応もあわせてしてください。
tanukitii

2018/10/20 00:39 編集

SQLをDBで実行したところ,データに追加されました。 try-catchにINSERT実行もいれたのですが,特になんのエラーも返ってきませんでした。 ちなみにコードは以下のように書きました。 <?php try{ $db = new PDO('mysql:dbname = mydb; host = 127.0.0.1; charset = utf8', '△△', '〇〇'); $count = $db -> exec('INSERT INTO my_items SET maker_id=1, item_name="もも", price=210, keyword="缶詰,ピンク,甘い", sales=0'); echo $count . '件のデータを挿入しました。'; }catch(PDOException $e){ echo "DB接続エラー:". $e->getMessage(); } ?> 以上です。何卒よろしくお願いします。
tanukitii

2018/10/20 00:49

実はそれも試したのですが,現状変わらずです…。 DBにも追加されていません…。
tanukitii

2018/10/20 01:07 編集

調べてよくわからなかったのですが,使っているエディタに問題があるってことはありますか? VScodeを使用しているのですが… 度々もうしわけございません。何卒よろしくお願いします。
m.ts10806

2018/10/20 01:15

エディタは関係ないと思います。 念のためエラー表示をonにしてみてください https://qiita.com/shotets/items/3c95aef631b2c5eadae5 あとは127.0.0.1をlocalhostにかえてみるとか。 質問本文に現在のコードを追記していただけますか? またこちらで想像で補完している部分が多いとよくないので、そのphpを実行している手順、環境詳細も追記していただければと。 再現確認を行いたいのでテーブル定義、というか使ってるテーブルのcreate文もご提示ください
m.ts10806

2018/10/20 01:55

えっと、質問本文に追記してください。
tanukitii

2018/10/20 08:11

申し訳ないです,勘違いしていました。今,本文に追記いたしました。
guest

0

php

1if($count === false) { echo "failed"; }

件数の出力前にチェックをしてください。

マニュアルを参考に

http://php.net/manual/ja/pdo.exec.php

投稿2018/10/19 15:06

編集2018/10/19 15:07
JinwonKim

総合スコア312

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

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

tanukitii

2018/10/20 00:10

ご回答ありがとうございます。 これを付け加えるのは普通でしたか…勉強不足でしたね… 参考になりました。
guest

0

リファレンスによれば、executeの戻り値は成功したSQL文の数ではなくて成否(TrueかFalse)が返ります。
http://php.net/manual/ja/pdostatement.execute.php

SQLで作用を及ぼした行数(ここでいえばInsertされた件数)を取得したいのであれば、やはりリファレンスになりますが「rowCount」が使えます。
http://php.net/manual/ja/pdostatement.rowcount.php

投稿2018/10/19 14:31

SatoshiMashino

総合スコア210

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

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

m.ts10806

2018/10/19 19:39

exec()を利用されているのでこっちですね。 http://php.net/manual/ja/pdo.exec.php > PDO::exec() は、発行した SQL ステートメントによって更新もしくは 削除された行数を返します。 1 行も作用しなかった場合、PDO::exec() は 0 を返します。
tanukitii

2018/10/20 00:07

ご回答誠にありがとうございます。 rowCountという関数は知らなかったので,今度使用してみることにします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問