สอบถามวิธีทำปุ่มค้นหาในเว็บบอร์ดโดยที่ค้นหาทั้งชื่อ+เนื้อความกระทู้และโพสต์ที่มาตอบนะครับ
แบบฟอร์มแก้ที่
inc/index.inc.php
ส่วนของ Query แก้ไขที่
index.php
Date :
2022-09-20 14:54:11
By :
{Cyberman}
แก้ที่ไฟล์ template ไฟล์ไหนก็ได้แล้วแต่ชอบให้แสดงตรงส่วนไหนของ page (แม้แต่สร้างไฟล์ใหม่ขึ้นมายังได้)
แนะนำแก้ที่ inc/main.inc.php เพราะเป็น templete หลัก
ส่วนฝั่ง server จะเขียนรับแบบ post หรือ ajax ก็ตามสะดวก
Date :
2022-09-20 14:57:38
By :
009
เอาปุ่มค้นหาไปใส่ใน inc/index.inc.php เรียบร้อยครับ แล้วต้องแก้Query
Code (PHP)
<?php
ini_set('display_errors', 1);
error_reporting(~0);
$strKeyword = null;
if(isset($_POST["txtKeyword"]))
{
$strKeyword = $_POST["txtKeyword"];
}
if(isset($_GET["txtKeyword"]))
{
$strKeyword = $_GET["txtKeyword"];
}
?>
<form name="frmSearch" method="post" action="<?php echo $_SERVER['SCRIPT_NAME'];?>">
<table border="1" align="center" style="width: 99%; max-width: 600px;">
<tr style="text-align: center;">
<th>ค้นหาภายใน
<input name="txtKeyword" type="text" id="txtKeyword" style="width: 300px;" value="<?php echo $strKeyword;?>">
<input type="submit" value="Search">
</th>
</tr>
</table>
</form>
แล้วต้องแก้ Query ใน index.php ให้เป็นยังไงครับ
Code (PHP)
<?php
require 'inc/mysqli.inc.php';
$PAGE = empty($_GET['page'])
? 1
: (int)$_GET['page'];
$ITEMS_PER_PAGE = 50;
$Max_PAGE = 9;
$START_OFFSET = ($PAGE - 1) * $ITEMS_PER_PAGE;
$result = $mysqli->query(
"
SELECT
`id`,
`title`,
`created`,
`name`,
`num_views`,
`num_comments`,
`last_commented`
FROM `topic`
ORDER BY `last_commented` DESC
LIMIT {$START_OFFSET}, {$ITEMS_PER_PAGE}
"
);
$ITEMS = array();
while ($item = $result->fetch_assoc()) {
$ITEMS[] = $item;
}
$result->free();
$result = $mysqli->query('SELECT COUNT(*) FROM `topic`');
$FOUND_ROWS = current($result->fetch_row());
$result->free();
$NUM_PAGES = ceil($FOUND_ROWS / $ITEMS_PER_PAGE);
$PAGE_TEMPLATE = 'inc/index.inc.php';
require 'inc/main.inc.php';
ประวัติการแก้ไข 2022-09-20 16:21:26 2022-09-20 16:21:31
Date :
2022-09-20 16:18:42
By :
minimono
ขอเล่าที่มาก่อนว่าผมอายุ39 จบปวช.อิเล็ค ทำงานลูกน้องร้านซ่อมเงินเดือน 8,000
อาจารย์เจ้าของเว็บบอร์ดแห่งหนึ่งท่านไปบวชเป็นพระสายธุดงค์ผมนับถือจึงรับมาช่วยดูแลโดยเพียงแค่เสียค่าเช่าโฮส+โดเมน ต้นฉบับเดิมใช้ ASP.net + mdb(microsoft access database) , MS SQL จึงเช่าโฮสที่เป็นวินโดว์เซิฟเวอร์แล้วเมื่อสิงหาคม 2565 ที่ผ่านมา siamwebhost และบริษัทในเครือทั้งหมดโดน Ransomware ทำให้ข้อมูลหายและไม่สามารถกู้กลับมาได้เลย ผมจึงคิดที่จะเปลี่ยนให้มัน้เป็น PHP + MySQL ทั้งหมด เพื่อที่ว่าจะได้ใช้โฮสที่เป็นลีนุกซ์ได้(หาเช่าได้ง่าย,ราคาถูกลงและคิดว่าโอกาสล่มอีกคงน้อยกว่า)
คำตอบ
1. จุดประสงค์หลักในการนำไปใช้งานคือแก้หน้าเว็บบอร์ดตามที่เล่าไปด้านบน
2. สิ่งคาดหวังสูงสุดจากการตั้งคำถามนี้คือให้มีปุ่มค้นหา(ทั้ง2เทเบิ้ล)แล้วแสดงผลในหน้าของตัวเอง
- ตอนนี้ได้ลองทำหน้าค้นหาแยกออกมาต่างหากโดยใช้วิธีจาก https://www.thaicreate.com/php/php-mysql-mysqli-search-paging.html // *ค้นหาได้เพียงเทเบิ้ลเดียวเลยยังไม่ได้ทำการจัดรูปแบบให้หน้าตามันเหมือนกันเพื่อเอาไปใช้งานจริง
3. พยายามใช้ google ค้นหาวิธีจากที่ต่างๆ เช่น https://www.mysqltutorial.org/mysql-inner-join.aspx ทำให้รู้แนวทางทำ INNER JOIN แต่มันแสดงแค่กระทู้ที่มีคนตอบและไม่ค้นหากระทู้ที่ไม่มีคนตอบ description is null
Code (PHP)
$conn = mysqli_connect($serverName,$userName,$userPassword,$dbName);
$sql = "SELECT * FROM chaiya_answer as T1 INNER JOIN chaiya_question as T2 ON T1.topic_id = T2.id
WHERE T2.title LIKE '%".$strKeyword."%' OR T1.description LIKE '%".$strKeyword."%' OR T2.description LIKE '%".$strKeyword."%' GROUP BY T1.topic_id ";
$query = mysqli_query($conn,$sql);
$num_rows = mysqli_num_rows($query);
ส่วนทั้ง 3 ลิงค์ข้อมูลเหมือนกันหมดผมเอาไปใส่ใว้เพื่อใครแก้ชุดไหนยังมีอีกชุด
Date :
2022-09-21 16:34:30
By :
minimono
เคยลองใช้ RIGHT JOIN , LEFT JOIN = แสดงทุกกระทู้แม้คนตอบ 0 หรือ chaiya_answer.description NULL
แต่
- ใช้เวลาในการประมวลผลนานมากกว่าจะแสดงรายการออกมา
- ใช้คำสั่งค้นหาไม่ได้
Code (PHP)
$sql = "SELECT * FROM chaiya_answer as T1 RIGHT JOIN chaiya_question as T2 ON T1.topic_id = T2.id
WHERE T2.title LIKE '%".$strKeyword."%' OR T1.description LIKE '%".$strKeyword."%' OR T2.description LIKE '%".$strKeyword."%' GROUP BY T2.id ";
$sql = "SELECT T1.id,title, T1.created,num_views,num_comments,last_commented FROM chaiya_question AS T1 LEFT JOIN chaiya_answer AS T2 ON T1.id = T2.topic_id
WHERE T1.title LIKE '%".$strKeyword."%' OR T1.description LIKE '%".$strKeyword."%' OR T2.description LIKE '%".$strKeyword."%' GROUP BY T1.id ";
Date :
2022-09-21 19:59:36
By :
minimono
GROUP BY T1. topic_id
GROUP BY T2. topic_id
t1 มันเป็น detail
t2 tป็น topic หลัก
Date :
2022-09-21 20:16:44
By :
Chaidhanan
พึ่งนึกแนวทางที่2ออก
นั่นคือในเรื่องของการทำปุ่มให้ค้นหาได้2ตารางโดยการใช้ INNER JOIN สามารถทำงานได้ดีแต่มันแสดงแค่กระทู้ที่มีคนตอบและไม่ค้นหากระทู้ที่ไม่มีคนตอบ **งั้นก็ไปทำให้มีคนตอบทุกกระทู้ซะซิ // ส่วนว่าจะตกแต่งหน้าตาหรือจับเอาไปรวมกันได้ค่อยว่าทีหลัง
Search2Table.php
Code (PHP)
<html>
<head>
<title>ThaiCreate.Com PHP & MySQL (mysqli)</title>
</head>
<body>
<?php
ini_set('display_errors', 1);
error_reporting(~0);
$strKeyword = null;
if(isset($_POST["txtKeyword"]))
{
$strKeyword = $_POST["txtKeyword"];
}
if(isset($_GET["txtKeyword"]))
{
$strKeyword = $_GET["txtKeyword"];
}
?>
<form name="frmSearch" method="post" action="<?php echo $_SERVER['SCRIPT_NAME'];?>">
<table width="599" border="1">
<tr>
<th>Keyword
<input name="txtKeyword" type="text" id="txtKeyword" value="<?php echo $strKeyword;?>">
<input type="submit" value="Search"></th>
</tr>
</table>
</form>
<?php
$serverName = "localhost";
$userName = "root";
$userPassword = "";
$dbName = "supap_php";
$conn = mysqli_connect($serverName,$userName,$userPassword,$dbName);
$sql = "SELECT T1.id,title, T1.created,num_views,num_comments,last_commented FROM chaiya_question AS T1 INNER JOIN chaiya_answer AS T2 ON T1.id = T2.topic_id
WHERE (T1.title LIKE '%".$strKeyword."%' OR T1.description LIKE '%".$strKeyword."%' OR T2.description LIKE '%".$strKeyword."%') GROUP BY T1.id ";
$query = mysqli_query($conn,$sql);
$num_rows = mysqli_num_rows($query);
$per_page = 50; // Per Page
$page = 1;
if(isset($_GET["Page"]))
{
$page = $_GET["Page"];
}
$prev_page = $page-1;
$next_page = $page+1;
$row_start = (($per_page*$page)-$per_page);
if($num_rows<=$per_page)
{
$num_pages =1;
}
else if(($num_rows % $per_page)==0)
{
$num_pages =($num_rows/$per_page) ;
}
else
{
$num_pages =($num_rows/$per_page)+1;
$num_pages = (int)$num_pages;
}
$row_end = $per_page * $page;
if($row_end > $num_rows)
{
$row_end = $num_rows;
}
$sql .= " ORDER BY T1.last_commented DESC LIMIT $row_start ,$per_page ";
$query = mysqli_query($conn,$sql);
?>
<table width="1200" border="1">
<tr>
<th width="91"> <div align="center">หมายเลข </div></th>
<th width="600"> <div align="center">หัวข้อ </div></th>
<th width="190"> <div align="center">โพสต์เมื่อ </div></th>
<th width="50"> <div align="center">ดู </div></th>
<th width="50"> <div align="center">ตอบ </div></th>
<th width="190"> <div align="center">โพสต์ล่าสุด </div></th>
</tr>
<?php
while($result=mysqli_fetch_array($query,MYSQLI_ASSOC))
{
?>
<tr>
<td><div align="center"><?php echo $result["id"];;?></div></td>
<td><?php echo $result["title"];?></td>
<td><?php echo $result["created"];?></td>
<td><div align="center"><?php echo $result["num_views"];?></div></td>
<td align="center"><?php echo $result["num_comments"];?></td>
<td align="right"><?php echo $result["last_commented"];?></td>
</tr>
<?php
}
?>
</table>
<br>
Total <?php echo $num_rows;?> Record : <?php echo $num_pages;?> Page :
<?php
if($prev_page)
{
echo " <a href='$_SERVER[SCRIPT_NAME]?Page=$prev_page&txtKeyword=$strKeyword'><< Back</a> ";
}
for($i=1; $i<=$num_pages; $i++){
if($i != $page)
{
echo "[ <a href='$_SERVER[SCRIPT_NAME]?Page=$i&txtKeyword=$strKeyword'>$i</a> ]";
}
else
{
echo "<b> $i </b>";
}
}
if($page!=$num_pages)
{
echo " <a href ='$_SERVER[SCRIPT_NAME]?Page=$next_page&txtKeyword=$strKeyword'>Next>></a> ";
}
$conn = null;
?>
</body>
</html>
Date :
2022-09-22 09:42:26
By :
minimono
การค้นหาโดยที่ไม่มีคนตอบ คือการค้นหาจาก topic(หัวข้อ) และ เนื้อหาของคำถาม ก็มีประโยชน์
แต่อยากให้แสดง ทั้งสองรายการ ต้อง group by จาก primary table ไม่ใช่ค้นหาจาก answer table
การ group by จาก table answer ถ้าไม่มีคนตอบ แล้วมันจะเอา อะไรมาแสดง
การ group by จาก table question คือไม่สนใจว่าจะมีคนตอบ หรือไม่
ที่นี้ คุณสมบัติของ mysql เมื่อทำการ group by
คือแสดงได้ทุก column โดยไม่สนใจ column ที่นำมา group by
แต่ที่นี้มันจะแสดงแค่ เรคคอร์ดที่ พบ โดยไม่ แสดง เรคคอร์ดอื่นๆ
ก็ต้องวิเคราะห์ความต้องการ ของเราวา่ต้องการแสดง อะไร
โดยการทำงานจริง เราต้องค้นหาจาก
1 ตาราง question
column topic (หัวข้อคำถาม)
column question detail (เนือหาคำถาม)
2 ตาราง answer
column answer detail (เนื้อหาคำตอบ)
เพื่อให้แสดง หัวข้อคำถาม หรือเนื้อหาคำถาม จาก ตาราง question ที่ค้นหาเจอ
และ ที่ค้นหาไม่เจอ แต่ มี คำตอบ ภายใต้คำถาม ที่ค้นหาได้
จำเป็นต้องใช้ left Join ไม่สามารถ ใช้ inner ่join ได้
เพื่อให้มีการแยก ตารางหลัก และ ตารางรอง ที่ต้องใช้ค้นหา
ถ้าใช้ inner join มันบังคับ answer table ต้องมี คำตอบ ถีง join ได้
Code (SQL)
SELECT T1.id,title, T1.created, num_views, num_comments, last_commented
FROM chaiya_question AS T1
left JOIN chaiya_answer AS T2 ON T1.id = T2.topic_id
WHERE concat(T1.title,' ',T1.description, ' ', t2.description ) LIKE '%คำค้น%'
group by T1.id
ก็ลองศึกษาดูครับ อธิบายขนาดนี้แล้ว คงนำไปใช้งานได้นะครับ
Date :
2022-09-22 10:26:24
By :
Chaidhanan
ผลการทดลองใช้ LEFT JOIN .....WHERE concat(T1.title,' ',T1.description, ' ', t2.description ) LIKE '%คำค้น%'
นั้นแสดงผลออกมาเหมือน INNER JOIN เพราะ t2.description มีค่าว่างไม่นำมารวม
ไปค้นพบวิธีใช้ concat_ws (T1.title,' ',T1.description, ' ', t2.description ) หรือ concat(T1.title,' ',T1.description, ' ', COALESCE(t2.description,' ') ) ทำให้แสดงผลครบหมด
แต่เมื่อสั่งค้นหาจะรอนานจนขึ้น Fatal error: Maximum execution time of 120 seconds exceeded
ไปค้นเจอกระทู้ https://www.thaicreate.com/php/forum/056392.html
แนะว่าให้ใส่ ini_set('max_execution_time', 300); //300 seconds = 5 minutes เพิ่มเข้าไป=แสดงผลการค้นหาได้แต่ต้องรอนานมาก
Date :
2022-09-22 14:02:47
By :
minimono
เป็นแค่ตัวอย่าง คนทำรู้ property ของแต่ละ field ก็ต้องปรับตามความเหมาะสม
concat(T1.title,' ',T1.description, ' ', coalesce( t2.description,'') )
กรณีต่างตาราง แยก คำสั่ง ก็น่าจะเร็วกว่า
Code (SQL)
SELECT T1.id,title, T1.created, num_views, num_comments, last_commented
FROM chaiya_question AS T1
left JOIN chaiya_answer AS T2
ON T1.id = T2.topic_id and t2.description LIKE '%คำค้น%'
WHERE concat(T1.title,' ',T1.description) LIKE '%คำค้น%' or count(T2.topic_id)>0
group by T1.id
Date :
2022-09-23 10:19:14
By :
Chaidhanan
Load balance : Server 01