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

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

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

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

PHP

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

Q&A

解決済

3回答

1467閲覧

sqlのLIKE検索について

退会済みユーザー

退会済みユーザー

総合スコア0

SQL

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

PHP

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

0グッド

0クリップ

投稿2018/04/02 12:26

編集2018/04/02 12:56

したい事
・複数のカラムを検索
・sqlのインジェクション対策

調べると$_POST['keyword']を直接渡すのはダメなので、bindParamを通して実行するとの事だったのですが複数のカラムを下記のようなLIKE検索するとダメでした。

詳しい方いましたらよろしくお願いします。

補足:$query = "SELECT * FROM sample_tb WHERE sample_nm LIKE '%".$_POST['keyword']."%' OR sample_body LIKE '%".$_POST['keyword']."%'ORDER by id DESC";

だと欲しい情報が取得できました。もちろんダメなのは承知しています。

カラムのsample_nmとsample_bodyに「東京」というワードが入っているレコードを取得したいです。

PHP

1 2$query = "SELECT * FROM sample_tb WHERE sample_nm LIKE :keyword OR sample_body LIKE :keyword ORDER by id DESC"; 3 4// prepare準備 5$stmt = $pdo->prepare($query); 6 7// sqlインジェクション対策 8$stmt->bindParam(':keyword', $_POST['keyword'], PDO::PARAM_STR); 9 10// excute実行 11$stmt->execute(); 12 13// 全行取得 14$rows = $stmt->fetchAll(); 15

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2018/04/02 12:34

エラーの有無、エラーがある場合はエラーを質問に追記してください(コメントとかで追記ではありません)
退会済みユーザー

退会済みユーザー

2018/04/02 12:35

また対象データと取得したいデータも追記しましょう
退会済みユーザー

退会済みユーザー

2018/04/02 12:51

検索結果が返ってこない状態です。$_POST['keyword'];で試したところ欲しい値が返ってきました。
退会済みユーザー

退会済みユーザー

2018/04/02 12:57

追記しました!
guest

回答3

0

PDOで名前付きパラメータを再利用するためにはエミュレートモードにしなくてはいけません

PHP

1 $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,true);

ただし、エミュレートモードはセキュリティ上避けるべきである
というのが一般的です
ところが・・・前回MANABIYAで徳丸先生の講演を聞いていたところ
「最近はエミュレートモードも安定してるからいいんじゃない?」的な
発言をされていて、うーむそういうものなのかぁとちょっと
認識が変わりつつあります。(曲解してたらごめんなさい)
きょうびエミュレートモードもチャレンジしてみてもよいかもしれません。

ちなみに$_POST['keyword']的な使い方について徳丸先生は
「変数に受けてやろうね」とのご指導でした。まったく同意です。

$keyword=filter_input(INPUT_POST,'keyword');
するだけですからね

ちなみにLIKEで処理していますが、ワイルドカードはユーザーに付けさせる
のでしょうか?完全一致ではない検索については、仕様をよく検討
されたほうがいいでしょう。

疑問符パラメータ

一応、プログラム処理がらくな疑問符パラメータの例
カラム名の指定がおかしかったので調整

try{ $pdo = new PDO($dsn, $user,$password); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $query = "SELECT * FROM sample_tb WHERE 0 "; $keyword=filter_input(INPUT_POST,'keyword'); $data=[]; if(!is_null($keyword)){ $query.="OR sample_nm LIKE ? "; $data[]=$keyword; $query.="OR sample_body LIKE ? "; $data[]=$keyword; } $query.="ORDER by id DESC "; $stmt = $pdo->prepare($query); $stmt->execute($data); $rows = $stmt->fetchAll(); print_r($rows); }catch(PDOException $e){ die($e->getMessage()); }

投稿2018/04/02 12:42

編集2018/04/02 13:03
yambejp

総合スコア114572

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

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

yambejp

2018/04/02 12:47

蛇足: bindParamの変数の評価はタイミングがあとになるので、 不要なトラブルをさけるのであれば bindValueで処理した方が楽かもしれません。
退会済みユーザー

退会済みユーザー

2018/04/02 12:52

bindValue検討してみます。
退会済みユーザー

退会済みユーザー

2018/04/02 12:58

検索に詳しくないのでまずは実装できる検索処理を一つずつ確認しています。
yambejp

2018/04/02 13:01

疑問符パラメータの方がよいかもしれないので、追記しておきました
guest

0

LIKE の検索に関しては下記を参考にすると良いです。
PHPでデータベースに接続するときのまとめ-LIKE

同名の名前付きプレースホルダの使用は、「エミュレーションがON」であることが必要です。
名前付きプレースホルダ

網羅的な記事になっているので、全体を読むことをオススメします。

余談

調べると$_POST['keyword']を直接渡すのはダメなので、bindParamを通して実行するとの事だったのですが複数のカラムを下記のようなLIKE検索するとダメでした。

ダメでしたでは、なにが出来なかったのか、全く分かりません。
回答側の負担になるので、詳細を記述してください。
エラーなのか?期待した結果が出ないのか?等々

投稿2018/04/02 12:36

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2018/04/02 12:47

上記のコード実行すると検索結果が返ってこなくなりました。$queryをグーロバル変数に変更すると欲しい値が取得できました。
guest

0

ベストアンサー

ワイルドカード検索を行いたい場合はbindParamで受け渡す前に"%変数%"の処理をすること。

あとグローバル変数は一旦変数に入れて再利用するとコンパクトになる。

※間違っていたら修正します。

<? // sql文作成 $query = "SELECT * FROM sample_tb WHERE sample_nm LIKE :keyword OR sample_body LIKE :keyword ORDER by id DESC"; // グーロバル変数は再利用すること $keyword=filter_input(INPUT_POST,'keyword'); // prepare準備 $stmt = $pdo->prepare($query); //ワイルドカード検索する場合はbindParamの前で付与すること $search_keyword = "%$keyword%"; // sqlインジェクション対策 $stmt->bindParam(':keyword', $search_keyword, PDO::PARAM_STR); // excute実行 $stmt->execute(); // 全行取得 $rows = $stmt->fetchAll(); ?>
一応欲しい結果は取得できました。

投稿2018/04/03 10:42

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2018/04/03 10:51

リンク先をちゃんと読んでください。。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問