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

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

ただいまの
回答率

90.49%

  • PHP

    20792questions

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

  • MySQL

    5999questions

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

PHPとMySQLを利用したOR検索の結果表示が意図通りにならない

解決済

回答 2

投稿 ・編集

  • 評価
  • クリップ 0
  • VIEW 1,871
退会済みユーザー

退会済みユーザー

失礼します。
phpとmysqlを利用したショッピングカートのシステムを作ることになったので、まず商品検索→検索結果の表示の部分から作ろうと思ってコードを書いたのですが、タイトル通りOR検索した時の出力が意図通りになりません。

データベースにはnameというカラムに「りんご」「みかん」「バナナ」「りんす」が存在します。

私がやりたいのは、「りんご みかん」と入力すると「りんご」と「みかん」の2つが出力される検索です。

以下がコードです。

<?php
//  HTTPヘッダーで文字コードを指定
header("Content-Type:text/html; charset=UTF-8");
?>
<?php
//h()関数の読み込み
require_once 'lib/h.php';
//checkinput()関数の読み込み
require_once 'lib/checkinput.php';

//POSTされたデータのチェック
$_POST = checkinput($_POST);

//三項演算子で検索文字列の有無を判定し処理
$data = isset($_POST['data']) ? trim($_POST['data']) : '';
//OR検索
$query = 'SELECT * FROM goods WHERE ';    //クエリ前半
$sql ="";
if($data){
    $count = 1;    //カウントを1にしておく
    $data = trim($data); //検索文字列の前後の空スペースだけを除去
    //全角スペースはmb_convert_kana()関数で半角スペースに変換
    $datalist = mb_convert_kana($data, 's');
    //検索ワードをスペースで分割して配列に格納
    $keyword = explode(" ",$datalist);
    //配列の数を数える
    $count = count($keyword);
    //空スペースで区切られた数によってSQL文を組み立てる
    for($i=0; $i<$count; $i++){//配列の数だけ繰り返す
     if($i!="0"){
     $sql = $sql." OR";
     }
    $sql = $sql." name LIKE :$keyword ".$i;
    }
}else{
    $count = 0;
}
//SQL文準備
$query = $query.$sql;
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
               "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<meta http-equiv="content-script-type" content="text/javascript" />
<meta http-equiv="content-style-type" content="text/css" />
<!--  StyleSheet記述
<link rel="stylesheet" href="./css/main.css" type="text/css" media="all" />
StyleSheet記述  -->
<!-- PAGE TITLE -->
<title>ページタイトル</title>
</head>
<body>
<?php
if(!empty($datalist)){
    try{
        $username = "root";
        $password = "root";
        $pdo = new PDO(
            'mysql:host=localhost;dbname=shop',
            $username,
            $password,
            array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));

        //プリペアドステートメントのエミュレーションを無効にする
        $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);
        //エラーが発生した場合、例外がスローされるようにする
        $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);

        //検索結果
        if($datalist <> ""){//検索窓が空なら検索しない
            //単ワードでの検索時
            if($count == 1){
                $datalist2 = '%'.$datalist.'%';    //検索文字列を%検索文字%とする
                $stmt = $pdo->prepare("SELECT * FROM goods WHERE name LIKE :datalist");
                $stmt->bindParam(':datalist',$datalist2,PDO::PARAM_STR);
                $stmt->execute(
                        );
                $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
                
            }//OR検索時
            elseif($count > 1){
                $stmt = $pdo->prepare($query);
                for($i=0; $i<$count; $i++){    //検索ワードの数だけ繰り返す
                    $keyword2[$i] = '%'.$keyword.'%';    //検索ワード1つ1つを%検索文字%にする
                    $holder = ':datalist'.$i;    //ホルダー用
                    $stmt->bindParam($holder,$keyword2[$i],PDO::PARAM_STR);
                }
                $res = $stmt->execute(
                        );
                $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
            }
        }


        if(count($result) == 0){
            print '<p>「'.h($data).'」はデータベースに登録がありません</p>';
        }else{
            print '<p>「'.h($data).'」はデータベースに登録がありました</p>';
?>
            <p>検索結果</p>
            <table>
            <tr>
                <th>商品名</th>
                <th>価格</th>
            </tr>
            
<?php
            foreach ($result as $row){
?>
            <tr>
                <td><?php print h($row['name']) ?></td>
                <td><?php print h($row['price']) ?></td>
            </tr>
<?php
            }
            print '</table>';
        }

//接続でいない場合、PDOException例外がスローされるのでキャッチする
    }catch(PDOException $e){
        print 'エラーが発生しました。。 内容:' . h($e->getMessage());
    }
}
?>
<p>検索したい文字列を入力</p>
<form action="list_s.php" method="POST" >
<input type="search" name ="data">
<input type="submit" value="検索">
</form>
</body>
</html>


「ん」と入力すると「データベースに登録があります」のメーッセージと共に「りんご」「みかん」「りんす」が出力されます。
しかし、「りんご みかん」と入力すると、「データベースに登録がありません」とメッセージが出力されます。
SQL文が間違っているのか、それともOR検索時の処理が間違っているのか(もしくはどちらも)自分では解決できなかったので質問させていただきました。

よろしくお願いします。
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

    //検索ワードをスペースで分割して配列に格納
    $keyword = explode(" ",$datalist);
    //配列の数を数える
    $count = count($datalist);
これって想定通りですか?
配列は$keywordのように見えるのですが。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/01/08 16:59

    気づきませんでした。
    完全にミスです。ありがとうございます。

    キャンセル

0

$sql = $sql." name LIKE :$datalist ".$i;
「:$datalist "」が「:datalist"」と思います

あと、以下で検索条件が1つの場合は処理を分けていますが、
必要ないと思います。
            //単ワードでの検索時
            if($count == 1){
                $datalist2 = '%'.$datalist.'%';    //検索文字列を%検索文字%とする
                $stmt = $pdo->prepare("SELECT * FROM goods WHERE name LIKE :datalist");
                $stmt->bindParam(':datalist',$datalist2,PDO::PARAM_STR);
                $stmt->execute(
                        );
                $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
                
            }

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/01/08 17:10

    ありがとうございます。
    $はいらないんですね。
    もしかしてdatalistではなくてkeywordなんですかね?

    キャンセル

関連した質問

同じタグがついた質問を見る

  • PHP

    20792questions

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

  • MySQL

    5999questions

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