PHP&MySQL技术问题:单条件搜索时!empty逻辑为何不生效?
修复多字段搜索功能的问题
我来帮你一步步排查并修复代码里的问题,你的核心问题出在条件数组构建逻辑错误、SQL语句拼接错误,还有一个PHP魔术常量的小问题,具体如下:
1. 先解决最显眼的错误:_LINE_未定义
PHP里获取当前行号的魔术常量是__LINE__(两个下划线),你写成了_LINE_,所以会抛出“undefined constant”的错误,把所有_LINE_改成__LINE__即可。
2. SQL语法错误:重复的WHERE子句
你的基础查询语句已经包含了WHERE子句:
SELECT * FROM tempahanbilik WHERE status!='BELUM DIPROSES' AND kosong = 'tidak' AND MONTH(tarikh) = 5 AND YEAR(tarikh) = YEAR(CURDATE()) AND YEAR(tarikh2) = YEAR(CURDATE())
但后面拼接条件时又加了WHERE,这会导致SQL出现两个WHERE,直接触发语法错误。应该改成用AND来拼接额外条件,还要注意空格(避免SQL变成...CURDATE()AND...这种非法格式)。
3. 条件数组构建的逻辑错误
你当前的代码把POST参数的值放进了$field数组,然后循环判断isset($_POST[$fields])——这完全逻辑颠倒了!比如$tarikh是$_POST['tahun']的值(比如2024),那isset($_POST['2024'])肯定是false,所以永远生成不了搜索条件。
正确的逻辑是:定义POST参数名和数据库字段名的对应关系,然后检查每个POST参数是否有输入,再生成对应的SQL条件。另外,你用的mysql_real_escape_string已经被废弃了,换成mysqli的$mysqli->real_escape_string()更安全,也符合你当前用的mysqli扩展。
修正后的完整代码
if(!empty($_POST['search4'])) { // 定义POST参数与数据库字段的映射 $searchMap = array( 'tahun' => 'tarikh', // POST的tahun对应数据库的tarikh字段(年份搜索) 'tempat' => 'tempat', 'sesi' => 'sesi', 'status' => 'status' ); $conditions = array(); foreach($searchMap as $postKey => $dbField) { // 检查当前POST参数是否非空 if(!empty($_POST[$postKey])) { $value = $mysqli->real_escape_string($_POST[$postKey]); // 针对年份的特殊处理:匹配tarikh的年份 if($postKey === 'tahun') { $conditions[] = "YEAR($dbField) = '$value'"; } else { $conditions[] = "$dbField LIKE '%$value%'"; } } } // 基础查询语句 $query = "SELECT * FROM tempahanbilik WHERE status!='BELUM DIPROSES' AND kosong = 'tidak' AND MONTH(tarikh) = 5 AND YEAR(tarikh) = YEAR(CURDATE()) AND YEAR(tarikh2) = YEAR(CURDATE())"; // 如果有额外搜索条件,拼接AND和条件(用括号包裹OR条件避免逻辑冲突) if(count($conditions) > 0) { $query .= " AND (" . implode(' OR ', $conditions) . ")"; } // 执行查询 $result = $mysqli->query($query) or die($mysqli->error . ' ' . __LINE__); $total = $result->num_rows; if($total > 0) { while($row = $result->fetch_assoc()) { $kp = $row['PenggunanoKP']; $a = "SELECT * FROM pengguna WHERE PenggunanoKP = '" . $mysqli->real_escape_string($kp) . "'"; $results = $mysqli->query($a) or die($mysqli->error . ' ' . __LINE__); $rows = $results->fetch_assoc(); // 在这里显示查询到的信息 } } else { echo" <tr> <td>-</td> <td>-</td> <td>-</td> <td>-</td> <td>-</td> <td>-</td> <td>-</td> <td>-</td> <td>-</td> <td>-</td> </tr>"; } }
额外说明
- 我把OR条件用括号包起来了,这样可以避免和基础查询里的AND逻辑发生优先级冲突,保证搜索条件的正确性。
- 移除了多余的
$total =1;语句,因为$total已经正确获取了查询结果的行数。 - 所有的变量都做了转义处理,避免SQL注入风险。
内容的提问来源于stack exchange,提问作者Hasifah Hassan
相关产品推荐
相关产品推荐

