PHP连接PostgreSQL全文搜索无结果时未显示提示问题
解决PostgreSQL全文搜索无匹配时无提示的问题
你的问题核心在于只检查了SQL查询是否执行成功,却没判断结果集里有没有实际数据。pg_query只要SQL语法没问题、执行不报错,就会返回一个资源对象——哪怕结果为空,if ($ret)也会判定为真,直接进入while循环,但因为没有数据,循环根本不会执行,页面自然就空白了。
修改后的完整代码示例
<?php $words = $_POST["search"]; // 先处理关键词,同时规避SQL注入风险 $processedQuery = replace(pg_escape_string($words) . ':*', ' ', '&'); $sql =<<<EOF SELECT pid, p_code, p_category, p_title, p_description, mf_cat, p_thumb FROM ( SELECT tblproducts.product_id as pid, tblproducts.product_code AS p_code, tblproducts.product_category AS p_category, tblproducts.product_title as p_title, tblproducts.product_description AS p_description, tblproducts.product_mf_catalog AS mf_cat, tblproducts.product_thumb AS p_thumb, setweight(to_tsvector(COALESCE(tblproducts.product_title)), 'A') || setweight(to_tsvector(COALESCE(tblproducts.product_description)), 'C') || setweight(to_tsvector(COALESCE(tblproducts.product_category)), 'B') || setweight(to_tsvector(COALESCE(tblproducts.product_code)), 'D') AS DOCUMENT FROM tblproducts GROUP BY tblproducts.product_id ) p_search WHERE mf_cat = '1' AND p_search.document @@ to_tsquery('english', '$processedQuery') ORDER BY ts_rank(p_search.document, to_tsquery('english', '$processedQuery')) DESC; EOF; $ret = pg_query($dbc, $sql) or die("Encountered an error when executing given sql statement: ". pg_last_error(). "<br/>"); ?> <!-- 结果展示部分 --> <?php if ($ret): ?> <?php $hasResults = false; ?> <?php while ($row = pg_fetch_row($ret)): ?> <?php $hasResults = true; ?> <div class='col-6 col-md-3 mb-4'> <div class='card-invis h-100'> <!-- 这里放你原来的内容渲染代码,比如: --> <h5><?php echo htmlspecialchars($row[3]); ?></h5> <p><?php echo htmlspecialchars(substr($row[4], 0, 100)); ?>...</p> </div> </div> <?php endwhile; ?> <!-- 无匹配时的提示 --> <?php if (!$hasResults): ?> <div class="col-12 text-center py-5"> <p>无记录找到</p> </div> <?php endif; ?> <?php endif; ?>
关键修改说明
新增结果存在性判断:
用$hasResults变量标记是否有数据被渲染,循环结束后如果变量仍为false,就显示“无记录找到”的提示。你也可以直接用pg_num_rows($ret) === 0来判断,效果一致:<?php if (pg_num_rows($ret) === 0): ?> <div class="col-12 text-center py-5"> <p>无记录找到</p> </div> <?php else: ?> <!-- 循环渲染结果 --> <?php endif; ?>修复SQL注入漏洞:
你原来的代码直接把$_POST["search"]拼进SQL,这是严重的安全隐患!上面的示例用pg_escape_string转义输入内容,避免恶意构造的关键词破坏SQL结构。更严谨的方式是使用参数绑定:$words = $_POST["search"]; $tsQuery = replace($words . ':*', ' ', '&'); $sql = "SELECT ... WHERE mf_cat = '1' AND p_search.document @@ to_tsquery('english', $1) ORDER BY ts_rank(p_search.document, to_tsquery('english', $1)) DESC"; $stmt = pg_prepare($dbc, "search_stmt", $sql); $ret = pg_execute($dbc, "search_stmt", array($tsQuery));
为什么原来的代码会空白?
pg_query执行成功时,无论结果集有没有数据,都会返回一个非false的资源对象,所以if ($ret)永远为真。你的代码只写了有数据时的渲染逻辑,完全没处理无数据的分支,自然就会显示空白。
内容的提问来源于stack exchange,提问作者Aaron
相关产品推荐
相关产品推荐

