You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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; ?>

关键修改说明

  1. 新增结果存在性判断:
    用$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; ?>
    
  2. 修复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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:00:29