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

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

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

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

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

Q&A

解決済

4回答

8985閲覧

MySQLの複数条件検索

Kokos

総合スコア15

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

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

0グッド

4クリップ

投稿2017/06/02 04:56

編集2017/06/06 01:37

WordpressにてMySQLのデータベースからデータを検索して
取り出す仕組みを作成しています。

二つのカラムに対してそれぞれ検索条件に一致する物を取り出し、
条件指定が無い場合は全て読み出すようにしたいと考えています。
この場合、どのように条件をプレースホルダへ渡せば良いでしょうか。

具体例は次の通りです。

テーブルには三種類のカラムがあります。
1.車名
2.メーカ
3.タイプ

検索条件(変数)は$makerと$typeの二種類で、
値はセレクトフォームからPOSTで取得する形です。

$maker="トヨタ", $type="セダン"の場合は問題なく該当車名が取り出せます。
$maker="トヨタ"でタイプを問わずに検索する、
$type="セダン"でメーカを問わずに検索する、
またはどちらも問わずに検索する場合の方法についてご教示いただけないでしょうか。

検索部分のコードは次の通りです。

php

1$maker = $_POST['maker']; 2$type = $_POST['type']; 3 4$sth = $wpdb->prepare("SELECT name FROM $wpdb->data WHERE maker = '%s' AND type = '%s'", $maker, $type); 5$rows = $wpdb->get_results($sth);

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

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

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

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

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

guest

回答4

0

プレースホルダーに値を送るんじゃなくて、emptyだったらWHEREを変えればいいんじゃないでしょうか?
単純なif文のような気がしますが。

投稿2017/06/02 05:01

shi_ue

総合スコア4437

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

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

Kokos

2017/06/05 02:42

ご回答いただきありがとうございます。 自分が知らない方法があるかなと複雑なことばかり考えていましたが、 確かにif文でSELECT文自体を場合分けしてしまえばシンプルに実現できますね。
guest

0

1.POSTされた$makerと$typeが両方とも空かどうか判定する

php

1if(isset($maker) && isset($type)){ 2 $sth = $wpdb->prepare("SELECT name FROM $wpdb->data "); 3}

あと、データベースには三種類のカラムがあります。 というのは、おそらく
テーブルには三種類のカラムがあります。が正解かと思います。

投稿2017/06/04 05:15

編集2017/06/04 05:16
imamoto_browser

総合スコア1161

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

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

Kokos

2017/06/06 01:38

ご回答いただきありがとうございます。 If文での分岐を使う場合は紹介いただいた方法で 判定し、SELECT文を変えるのが良さそうですね。 データベースと書いた点は、ご指摘の通りテーブルが正しい表現ですね。 質問文を修正しました。 ありがとうございました
guest

0

ベストアンサー

こんな感じじゃないですか?

PHP

1<form method="post"> 2maker:<input type="text" name="maker" value="トヨタ"><br> 3type:<input type="text" name="type" value="セダン"><br> 4<input type="submit" value="search"><br> 5</form> 6<?PHP 7$maker = filter_input(INPUT_POST,'maker'); 8$type = filter_input(INPUT_POST,'type'); 9$sql="SELECT name FROM tbl WHERE 1 "; 10$params=[]; 11if(!is_null($maker) and $maker!==""){ 12 $sql.="AND maker=%s "; 13 array_push($params,$maker); 14} 15if(!is_null($type) and $type!==""){ 16 $sql.="AND type=%s "; 17 array_push($params,$type); 18} 19array_unshift($params,$sql); 20 21print_r($params); 22//$sth =call_user_func_array(($wpdb,'prepare'),$params); 23?>

投稿2017/06/02 05:27

yambejp

総合スコア114839

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

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

Kokos

2017/06/05 02:37

コードまで合わせてご回答いただきありがとうございます。 $sth =call_user_func_array(($wpdb,'prepare'),$params); この部分で$paramsの引数を$wpdb->prepareに投げて実行しているのかと思いますが、HTTP ERROR500が出てしまいます。 原因が分かりそうでしたら教えていただけませんでしょうか。 (分からないなりにいじってみましたが、エラーは出ずとも検索結果も出ず...。)
yambejp

2017/06/05 02:43

失礼しました $sth =call_user_func_array(($wpdb,'prepare'),$params); ↓↓↓ $sth =call_user_func_array([$wpdb,'prepare'],$params); でどうでしょうか?
Kokos

2017/06/06 01:40

ありがとうございます。 無事、動作いたしました。 皆様からPHPでif文分岐、@パラメータへALLを渡すなど、 複数案をいただけましたので、 実環境でそれぞれ試してみて、合っているものを実装したいと思います。 皆様ありがとうございました。
guest

0

PHP は分からないので PHP で使える MySQL のプロバイダで可能かどうかわかりませんが・・・

クエリの WHERE 句を工夫して、例えば以下のようにし(プロバイダに Connector/NET を使った場合の例です)、条件指定がない場合はパラメータ @maker, @type に 'ALL' を渡す、指定がある場合は指定された値を渡すというのはいかがですか?

WHERE (@maker='ALL' OR maker=@maker) AND (@type='ALL' OR type=@type)

----- 2017/6/6 12:11 追記 -----

2017/06/06 11:53 の私のコメントで「詳しくは回答欄に書いておきます」と書きましたが、それを以下に書いておきます。

まず基本的な話として、パラメータ化クエリというのをご存知でしょうか? 

以下の記事によると PHP + MySQL でも使えるはずですので、SQL インジェクション防止とパフォーマンス向上のため必ず使うようにしてください。

パラメータ化クエリ
http://use-the-index-luke.com/ja/sql/where-clause/bind-parameters

質問者さんが最初の質問に書かれたコードを見ると、POST されてきたユーザー入力で SELECT クエリの文字列を組み立てているように見えますが、もしそうだとすると、それは SQL インジェクションしてくださいと言っているようなものです。なので、まずパラメータ化クエリを使うようにしてください。

パラメータ化クエリに関する知識が十分でないと話が通じにくいのですが、とりあえず @ のことについて書いておきます。

コメントにも書きましたが、パラメータ化の際のプレースホルダの命名規則には DB やプロバイダによっていろいろ違いがあり、頭に @ を付けるのは MySQL + Connector/NET を使った場合の規則です。

上に紹介した記事によると、PHP + MySQL では命名規則が異なるようで、疑問符 (?) で指定される位置パラメータマーカーが使用されるそうです。

なので、WHERE 句は、上に書いた @maker や @type のような名前付きパラメータではなくて、位置パラメータマーカー (?) を使って、

WHERE (?='ALL' OR maker=?) AND (?='ALL' OR type=?)

のようになると思います。

**注:PHP の開発環境を持っていないので未検証・未確認です。**もしハズレだったらすみません。

投稿2017/06/02 05:19

編集2017/06/06 03:12
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

Kokos

2017/06/06 01:39

ご回答いただきありがとうございます。 簡単に試してみましたが、うまく検索ができませんでした。 ただ、@を使った検索について私自身の不理解が大いにあると思うので 勉強してから再度試してみます。
退会済みユーザー

退会済みユーザー

2017/06/06 02:53

> @を使った検索について私自身の不理解が大いにあると思うので 「検索」ではないです。パラメータ化の際のプレースホルダの命名規則には DB やプロバイダによっていろいろ違いがあり、頭に @ を付けるのは MySQL + Connector/NET を使った場合の規則です。PHP では命名規則が異なると思います。 詳しくは回答欄に書いておきます。
Kokos

2017/06/08 07:02

詳細説明ありがとうございます。 プレースホルダの命名規則の事だったのですね。 勘違いしておりました。 Wordpressの場合、ご紹介いただいたウェブサイトで、PHPでのバインドパラメータの使い方にある、パラメータのバインドとエスケープ処理を$wpdb->prepare関数がやってくれるとの理解です... が、不安なのでもう少し調べて検証してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問