回答編集履歴
1
追記
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)」も併せて読むと良いです。
|