teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

3

追記

2020/10/07 12:19

投稿

tanat
tanat

スコア18778

answer CHANGED
@@ -21,7 +21,7 @@
21
21
 
22
22
  良くあるのは
23
23
  - SQLに直接連結している変数のうち、空の変数があって間違った文法のSQLになっている
24
- - そもそもSQLの文法にミスがある
24
+ - そもそもSQLの文法にミスがある(今回のケースだと、文字列の扱いが怪しい)
25
25
  あたりです。
26
26
 
27
27
  開発の流れ
@@ -29,10 +29,92 @@
29
29
 
30
30
  開発の流れは
31
31
 
32
- 1. 想定しているSQLをphpMyAdminやMySQLWorkbench、テスト用のPHPでも何でも良いのでまずは固定値で実行して、正しい(想定する)SQLを作成します
32
+ 1.想定しているSQLをphpMyAdminやMySQLWorkbench、テスト用のPHPでも何でも良いのでまずは固定値で実行して、正しい(想定する)SQLを作成します
33
- 2. [PHPマニュアル](https://www.php.net/manual/ja/pdo.prepare.php)を参考にして、値部分をプレースホルダーに置換して`prepare()`する。
34
- 3. 2のサンプルを参考にして、値を`execute()`や`bindParam()`でバインドする
35
33
 
34
+ 例えばこんな感じ。(実際のUPDATE文は自力で作って下さい&未チェックなのでエラーが出るかもしれませんが、流れを把握して頂ければ。)
35
+ * アクセスしたら想定通りの結果になるかSELECT文を発行して確認する
36
+
37
+ ```PHP
38
+ //アクセスしたらpileのID=1のタイトルが更新されるだけのPHP
39
+ $dsn = 'mysql:host=localhost;dbname=***;charset=utf8';
40
+ $user = '**';
41
+ $password = '*';
42
+ try{
43
+ $db = new PDO($dsn, $user, $password);
44
+ $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
45
+ $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
46
+ //プレースホルダーを使っていないので、冗長なサンプル
47
+ $stmt = $db->prepare("UPDATE `pile` SET title = 'テスト更新' WHERE id = 1");
48
+ $stmt->execute();
49
+ exit();
50
+ } catch (PDOException $e){
51
+ exit('データベースに接続できませんでした'.$e->getMessage());
52
+ }
53
+ ```
54
+
55
+ 2.[PHPマニュアル](https://www.php.net/manual/ja/pdo.prepare.php)を参考にして、値部分をプレースホルダーに置換して`prepare()`する。
56
+
57
+ ```PHP
58
+ //アクセスしたらpileのID=1のタイトルが更新されるだけのPHP
59
+ $dsn = 'mysql:host=localhost;dbname=***;charset=utf8';
60
+ $user = '**';
61
+ $password = '*';
62
+ try{
63
+ $db = new PDO($dsn, $user, $password);
64
+ $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
65
+ $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
66
+ //プレースホルダーを使っていないので、冗長なサンプル
67
+ $stmt = $db->prepare("UPDATE `pile` SET title = ':title' WHERE id = :id");
68
+ //この時点ではバインドしている変数が足りない旨の例外が発生するが、SQL文法エラーは発生しない
69
+ $stmt->execute();
70
+ exit();
71
+ } catch (PDOException $e){
72
+ exit('データベースに接続できませんでした'.$e->getMessage());
73
+ }
74
+ ```
75
+
76
+
77
+ 3.[PHPマニュアル](https://www.php.net/manual/ja/pdo.prepare.php)のサンプルを参考にして、値を`execute()`や`bindParam()`でバインドする
78
+
79
+ ```PHP
80
+ //アクセスしたらpileのID=1のタイトルが更新されるだけのPHP
81
+ $dsn = 'mysql:host=localhost;dbname=***;charset=utf8';
82
+ $user = '**';
83
+ $password = '*';
84
+ try{
85
+ $db = new PDO($dsn, $user, $password);
86
+ $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
87
+ $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
88
+ //プレースホルダーを使っていないので、冗長なサンプル
89
+ $stmt = $db->prepare("UPDATE `pile` SET title = ':title' WHERE id = :id");
90
+ $stmt->execute(array(':calories' => "テストタイトル", ':colour' => 1));
91
+ exit();
92
+ } catch (PDOException $e){
93
+ exit('データベースに接続できませんでした'.$e->getMessage());
94
+ }
95
+ ```
96
+
97
+ 4.バインド部分を変数に変更して、処理に組み込む
98
+ ```PHP
99
+ //アクセスしたらpileのID=1のタイトルが更新されるだけのPHP
100
+ $dsn = 'mysql:host=localhost;dbname=***;charset=utf8';
101
+ $user = '**';
102
+ $password = '*';
103
+ try{
104
+ $db = new PDO($dsn, $user, $password);
105
+ $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
106
+ $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
107
+ //プレースホルダーを使っていないので、冗長なサンプル
108
+ $stmt = $db->prepare("UPDATE `pile` SET title = ':title' WHERE id = :id");
109
+ $stmt->execute(array(':calories' => $title, ':colour' => $id));
110
+ exit();
111
+ } catch (PDOException $e){
112
+ exit('データベースに接続できませんでした'.$e->getMessage());
113
+ }
114
+ ```
115
+
116
+
117
+
36
118
  というような流れです。
37
119
  実行したいSQLに確信が持てない状態でPHPから実行するのは(現在そうであるように)どこが問題かの切り分けが発生するため難易度が高い方法です。
38
120
 

2

追記

2020/10/07 12:19

投稿

tanat
tanat

スコア18778

answer CHANGED
@@ -19,12 +19,17 @@
19
19
  そうすると、MySQLが返してくれるエラーメッセージが表示されるようになります。
20
20
  それを元にデバッグしてみてください。
21
21
 
22
+ 良くあるのは
23
+ - SQLに直接連結している変数のうち、空の変数があって間違った文法のSQLになっている
24
+ - そもそもSQLの文法にミスがある
25
+ あたりです。
26
+
22
27
  開発の流れ
23
28
  ---
24
29
 
25
30
  開発の流れは
26
31
 
27
- 1. 想定しているSQLをphpMyAdminやMySQLWorkbench、テスト用のPHPでも何でも良いのでまずは固定値で実行して、正しいSQLを作成します
32
+ 1. 想定しているSQLをphpMyAdminやMySQLWorkbench、テスト用のPHPでも何でも良いのでまずは固定値で実行して、正しい(想定する)SQLを作成します
28
33
  2. [PHPマニュアル](https://www.php.net/manual/ja/pdo.prepare.php)を参考にして、値部分をプレースホルダーに置換して`prepare()`する。
29
34
  3. 2のサンプルを参考にして、値を`execute()`や`bindParam()`でバインドする
30
35
 

1

修正

2020/10/07 12:06

投稿

tanat
tanat

スコア18778

answer CHANGED
@@ -1,7 +1,3 @@
1
- 前置き
2
- ---
3
- エラーメッセージはそのまま質問に載せてください
4
-
5
1
  回答
6
2
  ---
7
3