###やりたいこと
PHP、MySQLで検索機能を作成中です。
google等の検索窓のように、検索ワードをスペースで複数入力し検索するカタチを目指しています。
二つのテーブルを結合して、複数カラムのどちらかに含まれる複数の検索ワード(AND検索)を照会する検索機能を実装したいと考えています。
テーブル結合のうえ、複数ワードの検索機能は実装できたのですが、複数カラムに跨った検索が思うように実装できません。
例えば、下記のカラムの内容で「アカ テスト」と検索したときに、nameがアカでmessageにテストが含まれるpost_id1~3を取得したいです。
初学者のため、質問の仕方等、的を得ていない部分もあると思いますが、教えていただけると嬉しいです。
###テーブル構造とカラム
テーブル構造
テーブル Members
+-------------------+--------------+------+-----+-------------------+-----------------------------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+--------------+------+-----+-------------------+-----------------------------------------------+
| member_id | int | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| email | varchar(255) | NO | | NULL | |
| password | varchar(100) | NO | | NULL | |
| icon | varchar(100) | YES | | NULL | |
| member_created_at | datetime | NO | | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
| member_update_at | datetime | NO | | CURRENT_TIMESTAMP | DEFAULT_GENERATED on update CURRENT_TIMESTAMP |
+-------------------+--------------+------+-----+-------------------+-----------------------------------------------+
テーブル Post
+-----------+--------------+------+-----+-------------------+-------------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+-------------------+-------------------+
| post_id | int | NO | PRI | NULL | auto_increment |
| member_id | int | NO | | NULL | |
| message | varchar(560) | NO | | NULL | |
| post_date | datetime | NO | | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
+-----------+--------------+------+-----+-------------------+-------------------+
カラムの中身
PostテーブルとMembersテーブルを結合しカラムpost_id,name,messageを取得しました。
mysql> SELECT post_id,name,message FROM Post LEFT OUTER JOIN Members ON Post.member_id = Members.member_id;
+---------+--------+---------------------------------------------------+
| post_id | name | message |
+---------+--------+---------------------------------------------------+
| 1 | アカ | テスト文1 |
| 2 | アカ | テスト文2 |
| 3 | アカ | テスト文3 |
| 4 | アカ | 文1 |
| 5 | ao | aoの文1 |
| 6 | pink | pinkのテスト 文 1<br>555<br>333<br>桃 |
| 7 | pink | ピンク test 2<br><br>文章 |
+---------+--------+---------------------------------------------------+
####考えている構造
カラムをORで繋ぎ、繋いだ物をANDで絞り込みすることで実装できると考えました
word1検索(name or message) AND word2検索(name or message)
###現状のコード
"name LIKE '%$word%' OR message LIKE '%$word%'"で複数カラムから検索し、' . implode(' and ', $keyword) . 'でANDで絞り込みをしているつもりなのですが、出て欲しい検索結果になりません。
どのように直せば、複数カラムのいずれかに含まれる複数のワードを絞り込む検索機能を実装できるのか、教えて欲しいです。
php
1if( empty($_GET['keyword']) ) { 2 $error_message = 'キーワードを入力してください。'; 3} else { 4 $keyword = $_GET['keyword']; 5 //エスケープ処理 6 $keyword = htmlspecialchars( $keyword, ENT_QUOTES); 7 // 最初および最後から空白文字を取り除く 8 $keyword = trim($keyword); 9 //全角スペースを半角スペースへ 10 $keyword = preg_replace('/ /', ' ', $keyword); 11 //連続する半角スペースを1つの半角スペースに変換する 12 $keyword = preg_replace('/\s+/', ' ', $keyword); 13 // 文字列を分割して配列にする 14 $keyword_split = preg_split('/(\s| )+/', $keyword); 15} 16 17if(!isset($error_message)){ 18 19 try{ 20 // データベースに接続 21 $db = dbConnect(); 22 23 $sql2 = "SELECT * FROM Post 24 LEFT OUTER JOIN Members ON Post.member_id = Members.member_id "; 25 if ($keyword != '') { 26 $keyword = array(); 27 foreach ($keyword_split as $word) { 28 array_push($keyword, "name LIKE '%$word%' OR message LIKE '%$word%'"); 29 } 30 $sql2 .= ' WHERE (' . implode(' and ', $keyword) . ')'; 31 } 32 $sql2.=" ORDER BY post_date DESC"; 33 34 $stmt = $db->prepare($sql2); 35 $stmt->execute(); 36 echo "OK"; 37 echo "<br>"; 38 } catch(PDOException $e){ 39 echo "失敗:" . $e->getMessage() . "\n"; 40 exit(); 41 } 42} 43
###開発環境
php7.3
MySQL8
回答2件
あなたの回答
tips
プレビュー