
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>
No.6ベストアンサー
- 回答日時:
>> 検索窓になにも入力しないで検索すると
>> 下記エラーがでました。
おっと失礼しました!コーディングミスです。
>> 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 してないじゃん!?」
と思われるかもしれませんが、実はこれには先ほど発生したようなエラーも含まれてしまいます。よって、先ほどのエラーを潰せばこちらのエラーも直ることになります。
phpとmysqlでここまでの検索機能がつけられるのですね、
「楽天ショッピング」クラスのコードですね!
大変勉強になりました、ありがとうございました。
No.5
- 回答日時:
この回答への補足
xamppでやってみました。
検索窓になにも入力しないで検索すると
下記エラーがでました。
2つあるのですが、
どうすればよいでしょうか?
エラーの読み方がいまいち分かっていません。
(ファイル名は、kensaku5.phpです。)
Notice: Undefined variable: rows in C:\xampp\htdocs\test\kensaku5.php on line 56
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
No.4
- 回答日時:
bindParamを使わずに実行する方法はいろいろあります。
(というかbindParamよりはbindValueの方が推奨されますけどね…)
PDOの基本
http://qiita.com/mpyw/items/b00b72c5c95aac573b71 …
LIKE検索用のエスケープ
http://qiita.com/mpyw/items/b00b72c5c95aac573b71 …
可変長プレースホルダ
http://qiita.com/mpyw/items/b00b72c5c95aac573b71 …
あと、何でもかんでも「@」でエラー抑制するクセは直してください。
・自分で後で使う変数が未定義になってしまう可能性がある場合「初期化」を行ってください。
・$_GETや$_POSTの要素はfilter_input関数経由で受け取ってください。
$_GET, $_POSTなどを受け取る際の処理
http://qiita.com/mpyw/items/2f9955db1c02eeef43ea
No.3
- 回答日時:
>PDOを使ってlikeデータを抜き出したい場合、bindParamを使うらしいですが、使わなくてもよいのでしょうか?
PDOでデータを渡す方法はいくつかあります。
一番手っ取り早いのは埋め込む位置に「?」をおいて、executeする際に
配列でデータを渡す今回のタイプです
http://www.php.net/manual/ja/pdostatement.execut …
No.2
- 回答日時:
いくつかクリアすべきことがありそうすね
<?PHP
$sql ="SELECT 列名 FROM 表名 ";
$data=array();
$array1=array();
//先頭や後尾についてるスペースを削除
$text1=preg_replace("/^[\s ]+|[\s ]+$/","",$text1);
if($text1!==""){
//スペースで分割
$array1=preg_split("/[\s ]+/",$text1);
//前後に%をつけて前後方一致の形にしておく
array_walk($array1,create_function('&$val','$val="%".$val."%";'));
}
//WHERE句を作成
$sql.= "WHERE 1 ";
//$array1に要素が1つ以上あれば=検索語があれば
if(count($array1)>0){
$sql.="AND ( ";
//orでつないでいく
$sql.= implode("OR ",array_fill(0,count($array1),"列名1 LIKE ? "))." ";
//プレイスホルダ用
$data=array_merge($data,$array1);
//別の列を検索したい場合同様に
$sql.= "OR ";
$sql.= implode("OR ",array_fill(0,count($array1),"列名2 LIKE ? "))." ";
$data=array_merge($data,$array1);
$sql.=") ";
}
print $sql."<br>";
print_r($data);
$dsn = 'mysql:host=localhost; dbname='.$dbname;
$pdo = new PDO($dsn,$username,$password);
$stmt = $pdo->prepare( $sql);
$stmt->execute($data);
No.1
- 回答日時:
イマイチ「やりたいこと」が読み取りにくいのですが、こういうことですかね。
(例)
<?php
$sql = 'SELECT 列名 FROM 表名';
$text = isset($_POST['text']) ? str_replace(' ', ' ', $_POST['text']) : '';
$array = array_filter(explode(" ", $text), 'arr_sel'); // 空文字列を除外する
if (count($array) > 0) { // 検索文字があったら
$where = array();
$param = array();
foreach ($array as $value) {
$where[] = '((列名 like ?)or(列名 like ?))';
$param[] = '%' . addcslashes($value, '\\_%') . '%';
$param[] = '%' . addcslashes($value, '\\_%') . '%';
}
$sql .= ' where ' . implode('and', $where); // whereを組み立てる
}
if (isset($param)) { // 検索条件あり
$stmt = $pdo->prepare($sql);
$stmt->execute($param);
} else { // 検索条件なし
$stmt = $pdo->query($sql);
}
// 空文字列を除外するCALLBACK関数
function arr_sel($arg) {
return (trim($arg) !== "");
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) PHPプログラムをエクセルに張り付けると検索ボックスがでてくる! 3 2022/05/08 07:10
- PHP PHPでCookieを使った訪問回数について 1 2023/05/28 14:10
- AJAX JavascriptからPHPへのAjax通信でnullが返ってくる 3 2022/08/03 22:00
- PHP PHPで画像の渡しが上手く行きません。 1 2023/02/02 09:39
- CGI perlで書いたcgiでsqliteの使い方を教えてください 2 2023/05/08 21:29
- PHP php ログイン 1 2022/11/01 00:24
- PHP PHPのエラーの解消法について教えて下さい。 1 2023/02/06 10:48
- PHP 入力した部分を表示させたまま(保持)するにはどうすれば良いでしょうか? 1 2023/01/25 11:14
- PHP 重複を防ぐ記述について教えて下さい。 3 2023/04/03 14:35
- PHP htmlspecialcharsが機能していないです。 バグですか? 1 2022/04/05 01:22
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
プルダウンメニューにDBの内容...
-
String だと「 ByRef引数の型が...
-
C言語の配列をPush(追加)する...
-
CSVデータを使ったページングと...
-
$_SESSIONに二次元配列を使える...
-
mb_encode_numericentityでタグ...
-
PHP5でCSVの指定行データだけを...
-
pascalについて知りたいのです...
-
phpの掲示板で新しい順に表...
-
ファイルの書き込みについて教...
-
ネストが深い時のforeachはどう...
-
file_existsでファイル名の部分...
-
cakephpでのトランザクション処...
-
foreachで配列を、左から縦3列...
-
Array Array と表示される
-
読み(あ行~わ行)ごとに分け...
-
PHPで、CSVファイルを、指定し...
-
fgetsを使ってcsvからcsvに
-
ラジオボタンをランダムに表示...
-
readdirで文字化け
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
プルダウンメニューにDBの内容...
-
POSTで受け取った値をもとにJpG...
-
cakephp2.6でfindを使い合計値...
-
しりとり 無限ループ?
-
PHPの配列の初期化について
-
日付、時間の2段階でソート
-
多次元配列のカウント+1の仕方
-
phpとmysqlで「あいまい検索」...
-
順位を付ける時のスコアの重複...
-
PHP5の外部コマンド実行で、バ...
-
再帰的な順列書き出し
-
サイト名を取得するPHP
-
listへのappendが出来ない件
-
順位をつけたいです。
-
2次元配列の値の受け渡しについ...
-
$a[0]='w';$a[1]='r';を1回で
-
PHP配列をJavaScriptに渡したい
-
mysqlにinsertするとエラーがで...
-
$xml要素を階層指定して取得し...
-
バッチでFTPコマンド
おすすめ情報