ママのスキンケアのお悩みにおすすめアイテム

PDOでプリペアードステートメントを使って複数キーワードで検索する方法を教えて下さい。
プリペアードステートメントは「?」形式ではなく、$stmt->bindParam(':sample', $samle);の形を使った方法を知りたいです。

環境
PHP:5.1.6
MySQL:5.0.77


処理の流れを作ってみました。途中から不明な点があるので変数化しないで記載してあります。
/*--PDOのプリペアードステートメントのbindParamを用いた場合--*/

$dbh = new PDO($DSN , $DBUSER , $DBPASS);

$query = 'SELECT * FROM table WHERE ';
$keyword_str = 'キーワードA キーワードB キーワードC';
//全角スペースを半角スペースに変換する処理(省略)
$keywords = split(' ',$keyword_str);
for($a = 0; $a <$keywords_num; $a++)
{
$kw[]=' 列名 like :kw'.$a;
}
$query.= join('AND', $kw);

//キーワードごとに「%キーワード%」の形を作る。
$kw0='%'.$keywords[0].'%';
$kw1='%'.$keywords[1].'%';
$kw2='%'.$keywords[2].'%';

$stmt = $dbh->prepare($query);

$stmt->bindParam(':kw0', $kw0);
$stmt->bindParam(':kw1', $kw1);
$stmt->bindParam(':kw2', $kw2);

$stmt->execute();
/*-----------------------------------------------------------*/

上記ソースの後半部分、

(1)
//キーワードごとに「%キーワード%」の形を作る。
のところを変数を使って実現しようと思うのですが、うまくいきません。

$keywords_num=count($keywords);
でキーワードの数を取得して
for($a = 0; $a <=$keywords_num; $a++) {
//作りたいソース
}
の形にすることは予想がつくのですが。

(2)
$stmt->bindParam(':kw0', $kw0);
$stmt->bindParam(':kw1', $kw1);
$stmt->bindParam(':kw2', $kw2);
の部分も上記と同じ形を考えていますが
$keywords_num=count($keywords);
でキーワードの数を取得して
for($a = 0; $a <=$keywords_num; $a++) {
//作りたいソース
}

「//作りたいソース」の部分がうまく作れません。


(1)(2)の作りたいソース部分の書き方を教えて下さい。

上記の考え方より良い(短い)ソースが作れる場合はそのソースを教えて下さい。

このQ&Aに関連する最新のQ&A

A 回答 (2件)

可変変数を使えばいいと思います。



for($a = 0; $a <=$keywords_num; $a++) {
   ${'kw' . $a} = '%'.$keywords[$a].'%';
}
  :
  :
for($a = 0; $a <=$keywords_num; $a++) {
   $stmt->bindParam(':kw' . $a, ${'kw' . $a});
}
    • good
    • 0
この回答へのお礼

shimixさん

回答ありがとうございます。
可変変数というものを使うのですね。

可変変数を知らなかったので$a.$bのように普通に変数を連結したりしてみましたがどれもうまくいかない状態でした。

可変変数について調べて内容を理解することができました。

ソースだけでなく「可変変数」を使えば良いというキーワードを教えていただけることはとてもありがたいです。

プログラムを修正して動かしてみます。

お礼日時:2011/11/10 14:52

%付き文字列を変数に格納しなくても、bind 時に連結すれば?


<?php
// prepare 後
for($a = 0; $a <$keywords_num; $a++) {
$stmt->bindParam(':kw'.$a, '%'. $keywords[$a] .'%');
}

別解:名前付きホルダーにするなら連想配列を使う方法もある
<?php
// キーワードを配列に格納済みのところから
$holder_list = array();
$keywords_num = count($keywords);
for($a = 0; $a <$keywords_num; $a++) {
$kw[]=' 列名 like :kw'.$a;
//キーワードごとに「%キーワード%」の形を作る。 ホルダー名とも対応させる
$holder_list[':kw'.$a] = '%'. $keywords[$a] .'%';
}
$query.= join(' AND ', $kw);
var_dump($query, $holder_list);// debug 出力 本番ではコメントアウト
$stmt = $dbh->prepare($query);
foreach($holder_list as $holder => $word){
$stmt->bindParam($holder, $word);
}
$stmt->execute();
// 連想配列と、foreach 構文を覚えるといろんなところに使える。
    • good
    • 0
この回答へのお礼

mpro-gramさん

ご回答ありがとうございます。
>%付き文字列を変数に格納しなくても、bind 時に連結すれば?
そうですね。プログラムをもっと覚えてシンプルに作れるようになりたいです。

連想配列、foreach構文についてもしっかり学習したいと思います。
本などで基本的なことは学んだつもりでしたが、実際に自分でソースを作ってみると使いこなせていないことを実感します。

お礼日時:2011/11/10 15:03

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qphpで複数の検索語を検索対象にしたい

環境:php+mysql

やりたいこと:
半角や全角スペースの入った複数の検索語を検索対象にしたいです。
例:りんご みかん で検索されたキーワード

現在のコードは以下のとおりです。。
長くなるので、検索結果数だけの処理までを書いてます。
$sql の箇所で for文など使って繰り返し処理をさせればよいのかと思い
google先生で検索しましたが、、どうにも該当しそうなサイトが見つからず
アドバイスいただきたく質問させていただきました。


単語1つの場合だけ検索結果が正しく動きますが、
現在は、検索フォームに「りんご みかん」と入れると 検索結果ゼロになります。
これはこれで正しいのですが、、
希望は「りんご みかん」と入れると りんごとみかんを含む検索をしてほしい
と考えてます。

<?php
$keywords = $_GET["key"];

//検索キーワードのデータが何件あるか?

$sql="select * from item where title like '%".$keywords."%' or Description like '%".$keywords."%' or category like '%".$keywords."%' ";
$datas = mysql_query($sql , $db );
$num = mysql_num_rows($datas);
echo "検索結果は "."<span style=\"font-size:30px;\">".$num."</span>"."件です。<br>";
}

?>

環境:php+mysql

やりたいこと:
半角や全角スペースの入った複数の検索語を検索対象にしたいです。
例:りんご みかん で検索されたキーワード

現在のコードは以下のとおりです。。
長くなるので、検索結果数だけの処理までを書いてます。
$sql の箇所で for文など使って繰り返し処理をさせればよいのかと思い
google先生で検索しましたが、、どうにも該当しそうなサイトが見つからず
アドバイスいただきたく質問させていただきました。


単語1つの場合だけ検索結果が正しく動きますが、
現在は、検索フォ...続きを読む

Aベストアンサー

http://blog.olivesystem.com/824.html

Qillegal string offset

php5.3では動いていたプログラムをphp 5.4 で動かしたらwarning illegal string offsetが出て困っています。以下のプログラムでwarningが出ないようにするにはどのようにコーディングすればよいのでしょうか?


$a = array('exists' => 'foo');
if ($a['exists']['non_existent']) {
print 1;
}
print 2;
exit;

Aベストアンサー

isset()を使えばいいと思います

Qsyntax error, unexpected '}' というエラーの対処法

PHPを習い始めて三日目になるのですがParse error: syntax error, unexpected '}' in C:\Program Files\Apache Group\Apache2\htdocs\****\****\game.php on line 33
というエラーがでるのですが33行目前後のどこをなおせばいいのでしょうか?
・game.php
<html>
<head>
<title>数当てゲーム</title>
</head>
<body>
<h1 style="background:#cccccc">数当てゲーム</h1>
<form method="POST" action="game.php">
1~100までの数を入力してください
<input type="text" name="answer" size="5" maxlength="3" />
<input type="sbumit" value=回答" />
</form>
<hr />
<?php
session_start();
if(is_null($_SESSION['answer'])){
mt_stand(microtime()*1000000);
$_SESSION['answer']=mt_rand(1,100);
$_SESSION['game_cnt']=0;
}
if($_POST['answer']!=""){
$_SESSION['game_cnt']++;
if($_session['answer']==$_POST['answer']){
print("おめでとうございます".
$_SESSION['game_cnt']."回で正解しました!");
session_destroy();
}else{
if($_SESSION['answer']>$_POST['answer']){
print("もう少し大きいです。");
}else
print("もう少し小さいです。");
}
}
}
?>
</body>
</html>
それとこの間違えたところをなおしたあとはいつもコンピュータを再起動しないと修正したところが適用されないのですがほかに方法はないですか?基本的な質問ですいません。

PHPを習い始めて三日目になるのですがParse error: syntax error, unexpected '}' in C:\Program Files\Apache Group\Apache2\htdocs\****\****\game.php on line 33
というエラーがでるのですが33行目前後のどこをなおせばいいのでしょうか?
・game.php
<html>
<head>
<title>数当てゲーム</title>
</head>
<body>
<h1 style="background:#cccccc">数当てゲーム</h1>
<form method="POST" action="game.php">
1~100までの数を入力してください
<input type="text" name="answer" size="5" max...続きを読む

Aベストアンサー

print("もう少し大きいです。");
}else
print("もう少し小さいです。");
のelseの後に{がないようですが、大丈夫でしょうか?

Q文字列から、特定の文字を削除したい

アンケートで入力された値を受け取り、メールで送信しているのですが、受け取った値から、特定の文字列を削除することは可能でしょうか?

例えば電話番号の入力の場合、
03-xxxx-xxxx →03xxxxxxxx
077-xxx-xxxx →077xxxxxxx
のように、-(ハイフン)が入力されていたら、-を削除した文字列に置換してメール送信したいのです。
入力する時に、3つのテキストエリアに分けるのは諸事情でできないので、特定の文字を削除する関数か処理方法がありましたら、教えていただきたいです。
よろしくお願いします。

Aベストアンサー

str_replace
http://itbtech.itboost.co.jp/man/php_man/function.str-replace.html

<?php
$orig_telno = "03-xxxx-xxxx";

$telno = str_replace("-", "", $orig_telno);
echo $telno;

03xxxxxxxx

“PHP 文字列” あたりをキーワードに検索すれば
そんなに難しいものでもないような。

Q配列をPOSTで受けとる

タイトルのまんまですが
配列をformで送って
それをPOSTで受け取りたいのですが
うまくいきません

具体的に言うと
<?php
print"<form method=POST action=action.php>";

for($i=0; $i<$n; $i++){
   print"<input type=text name=foo[$i]>";
}
print"<input type=hidden name=n value=$n>";
print"<input type=submit value=go>";
print"<form>";
?>


///////////以下action.php//////////////////
<?php
$n = $_POST["n"];
for($j=0; $j<$n; $j++){
   $foo[$j] = $_POST["foo[$j]"];
   print"$foo[$j]";
}
?>


こんな感じのことがしたいのですが
うまくいきません
どうもPOSTされてないみたいでfoo[$j]はnullです
凡ミスな気がしなくもないんですが...プログラム初心者なんで↓↓
教えてください
よろしくお願いします

タイトルのまんまですが
配列をformで送って
それをPOSTで受け取りたいのですが
うまくいきません

具体的に言うと
<?php
print"<form method=POST action=action.php>";

for($i=0; $i<$n; $i++){
   print"<input type=text name=foo[$i]>";
}
print"<input type=hidden name=n value=$n>";
print"<input type=submit value=go>";
print"<form>";
?>


///////////以下action.php//////////////////
<?php
$n = $_POST["n"];
for($j=0; $j<$n; $j++){
   $foo[$j] = $_POST["foo[$j...続きを読む

Aベストアンサー

atsuGTさんこんにちは。


受け取り側は

$foo = $_POST["foo"];

とするだけで$fooに送信された配列が格納されます。


$_POST["foo[添え字]"] ではなく、
$_POST["foo"][添え字] となります。

QボタンをクリックでPHP文を実行

ボタンをクリックしたときのみPHP文を実行したいのですが・・・

<input type="button" onClink="<?php~?>">
でいけるかと思ったのですが、
ページ表示時に<?php~?>が実行されてしまい、うまくいきませんでした。

onClink="window.open(test.php)"
という方法以外でお願いします。

Aベストアンサー

AjaxはもともとJavaScriptの機能である非同期通信をつかったもので。Ajaxという言語があるわけではありません

Ajaxを利用するのであれば、JavaScriptのXMLHttpRequestを使って非同期通信できるような実装をしなくてはなりません
簡単にサンプルコードで書けるほど単純なものでもありません

一般的なサーバーサイドスクリプトの動作として、
ボタンを押す->サーバーへリクエストする->サーバーが処理する->クライアントに何かしらの結果を返す(出力する)です
つまり、PHP等のサーバーサイドスクリプトは、遷移させることが大前提で動作します

ですから、ボタンを押してその場でJavaScriptと同じようにPHPが動くなんてことはありえません。
ボタンを押したらサーバーにリクエストする という動作ならば可能です。

つまり
質問で言われているような
onClink="window.open(test.php)"

<form name="f1" action="test.php" method="post">
<input type="submit" name="submit" value="submit" />
</form>
等のような形になります

こういった一般的な方法だと いちいち画面が切り替わったようになってしまうのを嫌って Ajaxでコレと同じことを、画面を切り替えずに行っているだけに過ぎません

AjaxはもともとJavaScriptの機能である非同期通信をつかったもので。Ajaxという言語があるわけではありません

Ajaxを利用するのであれば、JavaScriptのXMLHttpRequestを使って非同期通信できるような実装をしなくてはなりません
簡単にサンプルコードで書けるほど単純なものでもありません

一般的なサーバーサイドスクリプトの動作として、
ボタンを押す->サーバーへリクエストする->サーバーが処理する->クライアントに何かしらの結果を返す(出力する)です
つまり、PHP等のサーバーサイドスクリプトは、...続きを読む

QPDOのprepareでLIKEの部分一致が使えません・・

http://d.hatena.ne.jp/Sybian/20070521/p1
のサイトの例のように、LIKE '%文字列%'
をprepareしようとしたのですが上手く結果が返りません。

PDOのプリペアステートメントは、
LIKEの部分一致や先頭一致に非対応なのでしょうか?

$query="SELECT * FROM table WHERE id=:id OR like name='%:name%'";

$pdo=new PDO('mysql:host=localhost;dbname=database','user','password');
$stmt=$pdo->prepare($query);
$stmt->bindValue(':id',$id,PDO::PARAM_INT);
$stmt->bindValue(':name',$name,PDO::PARAM_STR);
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);

Aベストアンサー

http://jp2.php.net/manual/ja/ref.pdo.php

Example#11 プレースホルダの間違った使用法
を注意してよく見てください

つまり $name の中に %がなくてはいけません

$query="SELECT * FROM table WHERE id=:id OR like name= :name ";
にして
$name = "%文%";
にすれば良い
ってことです

Qphpとmysqlで「あいまい検索」をしたいです。

phpとmysqlで「あいまい検索」をしようと思い、下記サイトを参考にしましたが、

http://d.hatena.ne.jp/akihito_sado/20120602/p1

PDOを使ってlikeデータを抜き出したい場合、bindParamを使うらしいですが、

http://rasukaru55.sitemix.jp/or_kensaku.php




下記の場合どう書き直すべきでしょうか?

打ち方が悪いのか、うまく作動しません。

教えてください。

※bindParamを使えばSQLインジェクション対策になっていると言う事でしょうか?


<html>
<head></head>
<body>
<?php
//POST送信されたデータを$text1へ
$text1 =@$_POST["text1"];

//SQL(テーブルから列を抽出する
$sql ="SELECT 列名 FROM 表名 ";
//キーワードが入力されているときはwhere以下を組み立てる
if (strlen($text1)>0){
//受け取ったキーワードの全角スペースを半角スペースに変換する
$text2 = str_replace(" ", " ", $text1);

//キーワードを空白で分割する
$array = explode(" ",$text2);

//分割された個々のキーワードをSQLの条件where句に反映する
$where = "WHERE ";

for($i = 0; $i <count($array);$i++){
$where .= "(列名 LIKE '%$array[$i]%')";

if ($i <count($array) -1){
$where .= " AND ";
}
}
//別カラムも同じ検索したい
$where2 = " OR ";

for($i = 0; $i <count($array);$i++){
$where2 .= "(2列名 LIKE '%$array[$i]%')";

if ($i <count($array) -1){
$where2 .= " AND ";
}
}
}


?>
<form method="POST" action="<?php echo $_SERVER["PHP_SELF"]?>">
<table>
<tr>
<td><input type="text" name="text1"></td>
<td><input type="submit" value="検索" name="sub1"></td>
</tr>
</table>
</form>
<?php
//組み立てたSQL分を表示する
echo "<p>組み立てたSQL分: ".$sql.@$where.@$where2;

?>
</body>
</html>

phpとmysqlで「あいまい検索」をしようと思い、下記サイトを参考にしましたが、

http://d.hatena.ne.jp/akihito_sado/20120602/p1

PDOを使ってlikeデータを抜き出したい場合、bindParamを使うらしいですが、

http://rasukaru55.sitemix.jp/or_kensaku.php




下記の場合どう書き直すべきでしょうか?

打ち方が悪いのか、うまく作動しません。

教えてください。

※bindParamを使えばSQLインジェクション対策になっていると言う事でしょうか?


<html>
<head></head>
<body>
<?php
//POST送信されたデータを$...続きを読む

Aベストアンサー

>> 検索窓になにも入力しないで検索すると
>> 下記エラーがでました。

おっと失礼しました!コーディングミスです。



>> Notice: Undefined variable: rows in C:\xampp\htdocs\test\kensaku5.php on line 56

「56行目で未定義の変数 $rows の値を使おうとしました」というエラーです。

// 件数をセット
$msg = count($rows) . '件見つかりました';

この部分を if ($keywords) { } の中の最後に含めてしまってください。現在の実装では入力が無い時は検索を実行しないようになっています(検索を実行しないとき $rows は定義されない)。



>> Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\test\kensaku5.php:56) in C:\xampp\htdocs\test\kensaku5.php on line 69

「69行目でヘッダー送信に失敗しました(ヘッダー送信は56行目で済んでいます)」というエラーです。

【HTTP入門】
http://www.tohoho-web.com/ex/http.htm

上記で説明されているContent-Typeヘッダーはデフォルトでは「Content-Type: text/html」となっており、文字コードの指定がされません。これでは文字化けしてしまう可能性があるので、header関数を使って

header('Content-Type: text/html; charset=utf-8');

として明示的に文字コードを指定したものに上書きすることで文字化けを防がなければいけません。上で示したリンク先の「応答メッセージ」のフォーマットを見てもらえれば分かると思いますが、

ヘッダー群(レスポンスヘッダー)→HTMLの内容(レスポンスボディ)

というコンテンツが空行1行を挟んで連続的に送信されていますよね。PHPでは何かの出力を "初めて" 行った時にレスポンスボディが送信され始め、そのときレスポンスヘッダーも全部送られてしまうのです。レスポンスヘッダーの送信は1回しか出来ないため、それ以降でheader関数を使おうとするとこのエラーが発生します。

「56行目で何も echo してないじゃん!?」

と思われるかもしれませんが、実はこれには先ほど発生したようなエラーも含まれてしまいます。よって、先ほどのエラーを潰せばこちらのエラーも直ることになります。

>> 検索窓になにも入力しないで検索すると
>> 下記エラーがでました。

おっと失礼しました!コーディングミスです。



>> Notice: Undefined variable: rows in C:\xampp\htdocs\test\kensaku5.php on line 56

「56行目で未定義の変数 $rows の値を使おうとしました」というエラーです。

// 件数をセット
$msg = count($rows) . '件見つかりました';

この部分を if ($keywords) { } の中の最後に含めてしまってください。現在の実装では入力が無い時は検索を実行しないようになっています(検索を実行しない...続きを読む

Q複数フィールド対してLIKE '% %' したい

SQL初心者なのですが、複数のフィールドをターゲットにしたフリーワード検索用のSQL文の書き方が解らず困っております。
例えば以下の様に"責任者"フィールドを限定して"田中"さんを探す事は出来るのですが、
----------------------------------------------------------------
SELECT * FROM `会員表` WHERE 責任者 LIKE '%田中%'
----------------------------------------------------------------
複数の、例えば以下の3つの
●責任者フィールド
●担当者フィールド
●顧客フィールド
全てを対象に一括で”田中”さんを検索したい場合、
どのように記述すれば良いのでしょうか?

どなたか有識者の方いらっしゃいましたら宜しくお願いします!!

Aベストアンサー

#1さんの方法はお勧めできません。

1)インデックスがきかない
2)セパレータを用いていない

1)に関しては、そもそも前後に%をいれた時点で、きかないので
あまり気にすることもないかもしれませんが、2)に関しては
たとえば、「責任者=吉田,担当者=中村」さんでもヒットします。
これはセパレータに適当な区切り文字を入れる必要があるでしょう。

まっとうに考えれば

(責任者 LIKE '%田中%'
OR 担当者 LIKE '%田中%'
OR 顧客 LIKE '%田中%')
とかじゃないですかねぇ

QFORMで送信ボタンと戻るボタンを2つつけてそれぞれ遷移先を変えたい

  
以下のような画面を作りたいのですが↓

--------------------------------------------------------------------------------
● a.php (ユーザ情報入力画面) ※フォームに入力する画面
 
 <FORM method="POST" action="b.php">
  <INPUT type="text" name="mail">
  <INPUT type="submit" name="submit" value="確認">
 </FORM>

● b.php (ユーザ情報入力確認画面)※フォームに入力された値を表示する画面

 <FORM method="POST" action="c.php">
  <!-- ここには、フォームに入力された値を表示する -->
  <INPUT type="submit" name="submit" value="登録"> // c.php に遷移する
  <INPUT type="submit" name="submit" value="戻る"> // a.php に戻る
 </FORM>

● c.php (完了画面)
--------------------------------------------------------------------------------
b.php について質問なのですが、
b.phpにおいて、登録ボタンと戻るボタンを2つつけて、
それぞれ遷移先を変えたいのですが、どうすればいいんでしょうか・・・?
<FORM method="POST" action="c.php">と書いてしまうと、
戻るボタンを押しても戻らずに、c.phpに遷移してしまいますよね??
こういう場合ってJavaScriptとかで遷移先を指定するんですか・・?
もしそうでしたら、JavaScriptがよくわからないので
できればサンプルコード示していただけると助かります・・・。
  

  
以下のような画面を作りたいのですが↓

--------------------------------------------------------------------------------
● a.php (ユーザ情報入力画面) ※フォームに入力する画面
 
 <FORM method="POST" action="b.php">
  <INPUT type="text" name="mail">
  <INPUT type="submit" name="submit" value="確認">
 </FORM>

● b.php (ユーザ情報入力確認画面)※フォームに入力された値を表示する画面

 <FORM method="POST" action="c.php">
  <!-- ここには、フォームに入...続きを読む

Aベストアンサー

はじめまして。

<INPUT type="submit" name="submit" value="登録" onClick="form.action='c.php';return true">
<INPUT type="submit" name="submit" value="戻る" onClick="form.action='a.php';return true">

でいいと思います。(実際、このコードで使っています)
値を渡すには、FORM内にhiddenで、値を設定しておいて、methodをPOSTに設定しておけば、渡せます。


人気Q&Aランキング