回答編集履歴

1

追記

2019/08/17 22:31

投稿

退会済みユーザー
test CHANGED
@@ -3,3 +3,59 @@
3
3
 
4
4
 
5
5
  LIKE はチョットめんどいですよ
6
+
7
+
8
+
9
+ # **以下、追記**
10
+
11
+ まだクローズされていないので追記しておきます。
12
+
13
+
14
+
15
+ > selectのWHEREで変数を使いたい
16
+
17
+
18
+
19
+ 質問は「SELECT の WHERE の[リテラル](https://dev.mysql.com/doc/refman/5.6/ja/literals.html)を変数として使いたい」と読み替えることができます。
20
+
21
+
22
+
23
+ リテラルを変数で表現するには、プリペアドステートメントを使用し、クエリの構文とデータを分離し、構文を改変できないようにした上で、データをバインドする方法が[推奨](https://www.ipa.go.jp/files/000017316.pdf)されてます。
24
+
25
+
26
+
27
+ 質問では、せっかく prepare() を使用しているにも関わらず、適切なプリペアードステートメントが記述でされていません。変数を SQL 文に埋め込んでいるため、構文の改変を許してしまっています。
28
+
29
+
30
+
31
+ 正しい記述方法に関しては、[PHP で MySQL 接続時に必要な知識(最小限版)](https://qiita.com/te2ji/items/56c194b6cb9898d10f7f)を参照してください。
32
+
33
+
34
+
35
+ (**余談**:プリペアードステートメントで記述したクエリが DB でどの様にあつかわれるかは、[「13.5 準備済みステートメントのための SQL 構文 - dev.mysql.com」](https://dev.mysql.com/doc/refman/5.6/ja/sql-syntax-prepared-statements.html)の1番目のサンプルを見ておくと、イメージしやすいと思います。)
36
+
37
+
38
+
39
+ また、LIKE に関しても注意が必要です。
40
+
41
+ プリペアードステートメントを使用したデータバインドでは、エスケープやクオートは自動で判断されますが、ワイルドカード文字はその対象ではないため、自前でエスケープを記述する必要があります。
42
+
43
+ ワイルドカード文字はデータベースによって違いがあるため、データベースのマニュアルで必要な文字を確認しエスケープしてください。
44
+
45
+
46
+
47
+ 本件が MySQL であれば、後方のみで使用しているので
48
+
49
+ `bindValue(1, addcslashes($hani, '\_%') . '%', PDO::PARAM_STR);`
50
+
51
+ のような記述になります。
52
+
53
+
54
+
55
+ エスケープが正しく行われていない場合、例えば $hani に「%01」のような値が突っ込まれると「%01%」をバインドしてしまい、意図した内容ではない検索が行われます。
56
+
57
+ DB 処理では、製作者の意図しない挙動を制限する必要があるのでワイルドカード文字に対してのエスケープは必須です。
58
+
59
+
60
+
61
+ 参考記事で紹介している範囲は php でデータベース接続を扱うため必要なの最小限の知識なので、もっと詳しく説明している「[PHPでデータベースに接続するときのまとめ](https://qiita.com/mpyw/items/b00b72c5c95aac573b71)」も併せて読むと良いです。