【问题标题】:search not returning query搜索不返回查询
【发布时间】:2021-12-20 19:55:31
【问题描述】:

对不起我的英语。我正在尝试搜索包含主题标签的 mysql 数据库,但它返回所有。

例如搜索#NBA 返回:#NBA、#NBA2021、#NBAscoreBoard 等

我在这里尝试了所有 preg_replace。 eg#(^|\s)#(\w*[a-zA-Z_]+\w*)#但是遇到具体搜索后怎么break呢?

$_GET["tag"]='#nba'; // $_GET is from a  query string

$fulltag = preg_replace("/[^a-zA-Z0-9_]/", '', $_GET["tag"]); //trying to isolate this problem 

 $sql='SELECT * FROM status WHERE data LIKE "%#'.$fulltag.'%" LIMIT 12';
    // 
    //
    //
echo //the result containing the "# $fulltag";

【问题讨论】:

  • 我们不是在几个小时前看到的吗
  • 是的,但它没有那么多代码
  • 您是否尝试过简单的"%#'.$fulltag.'",在您的条件后不使用通配符
  • 是的,但它希望这是字符串的结尾。如果主题标签后有任何内容,则从搜索中省略
  • 为什么不只做两个查询,一个用于 if data = fullTag,如果什么都不返回,那么进行通配符搜索?

标签: php regex hashtag


【解决方案1】:

正如我在评论中所说的那样——只做两个查询,一个来测试是否data = fullTag,然后如果什么都不返回,那么进行通配符搜索——可能会更简单。

但是,如果您真的希望这是一个单独的查询,您可以执行类似的操作,在其中测试它是否在子查询中完全匹配,然后按是否完全匹配排序,以便如果有完全匹配,它将是第一个结果。

SELECT * 
FROM (
SELECT 
  data,
  CASE 
    WHEN data = "#NBA"
      THEN 1
    ELSE 0
   END AS is_exact
FROM status 
WHERE data LIKE "%#NBA%"
LIMIT 12
) AS matches
ORDER BY is_exact DESC

单独说明:您现在的代码很容易受到SQL Injection 的攻击。您应该尝试使用参数化的预处理语句,而不是手动构建查询。请参阅 PDOMySQLi 准备好的语句。

以下是使用 PDO 和this method of using CONCAT 的上述查询示例,可安全地将通配符添加到您的查询中:

$_GET["tag"]='#nba'; // $_GET is from a  query string

$fulltag = preg_replace("/[^a-zA-Z0-9_]/", '', $_GET["tag"]); //trying to isolate this problem 

$pdo = new PDO(/* your connection details */);

 $sql = 
    'SELECT * 
    FROM (
        SELECT 
            data,
            CASE 
                WHEN data = CONCAT("#", :tag1)
                THEN 1
                ELSE 0
            END AS is_exact
        FROM status 
        WHERE data LIKE CONCAT("%#", :tag2, "%")
        LIMIT 12
    ) AS matches
    ORDER BY is_exact DESC
';

$stmt = $pdo->prepare($sql);
$stmt->execute([
    ':tag1' => $fulltag,
    ':tag2' => $fulltag,
]);

这是您使用相同、更安全的方法的更简单的查询:

$_GET["tag"]='#nba'; // $_GET is from a  query string

$fulltag = preg_replace("/[^a-zA-Z0-9_]/", '', $_GET["tag"]); //trying to isolate this problem 

$pdo = new PDO(/* your connection details */);

$sql = 'SELECT * FROM status WHERE data LIKE CONCAT("%#", :fullTag, "%") LIMIT 12';

$stmt = $pdo->prepare($sql);
$stmt->execute([':fullTag' => $fulltag]);

【讨论】:

  • 我要带它去试驾。我很感激。代码中还有很多其他安全问题,但我将它们排除在外,因为它们会分散 preg_replace/match 问题的注意力。谢谢
猜你喜欢
  • 2021-02-10
  • 1970-01-01
  • 2019-10-11
  • 2013-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-13
  • 1970-01-01
相关资源
最近更新 更多