【问题标题】:How to check the occurrence of the words in the SQL of a sentence using PHP and html如何使用PHP和html检查句子SQL中单词的出现
【发布时间】:2020-09-06 14:16:32
【问题描述】:

我从用户输入中得到一个句子,然后将其切成单词并将它们列在一个数组中。

之后,我想根据句子中的单词数将此数组传递给 SQL 查询,该查询将分别检查每个单词的出现,然后返回数字。

第一部分是使用正则表达式完成的:

preg_match_all('/<[^>]++>|[^<>\s]++/', $sent, $tokens);
print_r($tokens);

输出是这样的:

但是对于 SQL 查询循环,我被卡住了。我不知道从哪里开始我的数据库表是这样的:

我的预期输出是这样的:

P.S.:- 我认为PHP代码应该先知道用户输入句子的长度,然后对其进行分词以将单词传递给SQL循环查询以单独搜索。

【问题讨论】:

  • SELECT word, COUNT(word) as freq FROM tbl_words WHERE word IN ("hi", "how", "are", "you")?
  • @Justinas 每次用户使用不同的句子时,句子都会有所不同,所以它应该是一个循环,而不是我在查询中一个一个地输入单词
  • 当这个词在数据库中不存在时它应该返回 0
  • 在 PHP 中获取单独的单词,将它们添加到 IN 条件,返回 PHP 循环单词并检查它是否存在于返回的集合中,如果是 - 使用信息,如果不 - 添加 0
  • @programmingfreak 我已经添加了一整套代码,您可能可以在您身边复制这些代码

标签: php html mysql sql


【解决方案1】:

试试这个。我将逐步解释代码。

<?php
    $sentence = '';
    $result = '';

    if (isset($_GET['sentence'])) {
        $sentence = $_GET['sentence'];
        $tokens = tokenize($sentence);

        $mysqli = new mysqli('localhost', 'user', 'pass', 'dbname');
        $sql = getSQL($tokens, $mysqli);
        $result = $mysqli->query($sql);
    }

    function tokenize($sent) {
        preg_match_all('/<[^>]++>|[^<>\s]++/', $sent, $tokens);
        return $tokens[0];
    }

    function getSQL($tokens, $mysqli) {
        $sql = array();
        foreach ($tokens as $token) {
            $sql[] = sprintf("select '%s', ifnull(min(freq), 0) from test where word = '%s' ",
                $mysqli->real_escape_string($token),
                $mysqli->real_escape_string($token)
            );
        }
        return implode(' union all ', $sql);
    }
?>
<!doctype html>
<form method="get">
sentence: <input type="text" name="sentence" value="<?php echo $sentence; ?>"/>
</form>

<?php
if ($result !== ''):
?>

<div>
    <table border="1">
        <tr>
            <th>word</th>
            <th>freq</th>
        </tr>
<?php
    while ($row = $result->fetch_row()):
?>
        <tr>
            <td><?php echo $row[0]; ?></td>
            <td><?php echo $row[1]; ?></td>
        </tr>
<?php
    endwhile;
?>
    </table>

<?php
endif;
?>

</div>
</form>

HTML 代码之上的 PHP 代码

我们将sentenceresult 变量设置为空。我们将用户输入的内容存储到变量句中。结果将是 MySQL 的结果。

if (isset($_GET['sentence'])) { ... } 块检查网页是否有名为sentence 的查询字符串。如果我们收到了那个查询字符串,那就做点什么。否则什么都不做。

在该块中,我们依次执行以下操作:

  • 将用户提供的句子存储在变量中
  • 使用 preg_match_all 方法标记句子
  • 动态创建 SQL
  • 执行 SQL 并将输出存储在 results 变量中

function tokenize 是不言自明的。就像你注意到的那样,它接受句子并输出一个数组。

SQL 创建

你可以像这样询问 MySQL 的频率

select freq from test where word = 'bogus';

如果没有“hi”这个词,您将得不到任何结果。为了强制结果,您可以要求提供一个摘要,如计数、最小值、最大值等。

select min(freq) from test where word = 'bogus';

结果

+-----------+
| min(freq) |
+-----------+
|      NULL |
+-----------+

如果我们要求 MySQL 像这样用零替换 NULL:

select ifnull(min(freq), 0) from test where word = 'bogus';

你会得到:

+----------------------+
| ifnull(min(freq), 0) |
+----------------------+
|                    0 |
+----------------------+

因此,我们将利用这一点并询问:

select 'hi', ifnull(min(freq), 0) from test where word = 'hi';

如果 'hi' 不存在,你会得到 ​​p>

+----+----------------------+
| hi | ifnull(min(freq), 0) |
+----+----------------------+
| hi |                    0 |
+----+----------------------+

现在,您可以像这样组合多个查询:

select 'hi', ifnull(min(freq), 0) from test where word = 'hi'
union all
select 'how', ifnull(min(freq), 0) from test where word = 'how';

得到

+-----+----------------------+
| hi  | ifnull(min(freq), 0) |
+-----+----------------------+
| hi  |                    0 |
| how |                    5 |
+-----+----------------------+

太好了。所以,让我们尝试获取所有令牌并创建一个UNION ALL 查询。

function getSQL 就是这样做的。它遍历每个令牌并将每个select ... 查询存储在数组中。

请注意,我在 mysqli 中使用 real_escape_string 功能来转义特殊字符并使查询更安全。

然后,我们将所有选择查询连接在一起,并使用implode 函数将union all 放在它们之间。

一旦我们收到查询返回,我们使用$mysqli-&gt;execute($sql) 执行它。这会为我们返回结果。

HTML 部分

我们使用 GET 方法创建一个表单,以便将句子作为查询字符串返回。如果是第一次加载页面,$sentence 将为空。我们将其发布在 value 属性中。如果页面是使用查询字符串调用的,$sentence 将包含用户输入的内容。

<form method="get">
sentence: <input type="text" name="sentence" value="<?php echo $sentence; ?>"/>
</form>

那么,

<?php
if ($result !== ''):
?>

<div>
...
</div>

<?php
endif;
?>

仅当$result 不是空字符串时才会发布。当页面加载(或查询失败)时,$result 为空。因此,该块将不可见。如果查询成功,$result 将不为空,并且该块将可见。

表创建

我们创建表并放入内联 PHP。我们一一遍历记录并发布令牌和频率。如前所述,那些没有频率的词将显示为零。

试试看。另请注意,可以对此代码进行其他几项改进,但这只是一个开始。

【讨论】:

  • 最佳答案 最佳解释 没什么好说的,谢谢你让我开心
【解决方案2】:
$words = array();
while (...) {
    $word = ...;  // extract the word
    $words[] = "'$word'";
}
$in_list = implode(', ', $words);  //  'hi', 'how', 'are', 'you'
$sql = "SELECT  word,
                COUNT(*) as freq   -- COUNT(*) is the common syntax
            FROM tbl_words 
            WHERE word IN ($in_list)";
... $sql ...   // perform the query and deal with the results

要进行更新,请生成并执行:

$sql = "UPDATE tbl_words
            SET freq = freq + 1
            WHERE word IN ($in_list)";

如果一个句子可以有一个单词两次,你想让表格增加两次吗?不管你愿不愿意,我可能会构建一个哈希而不是数组:

$words = array();
while (...) {
    $word = ...;  // extract the word
    $words[$word] = (isset($words[$word]) ? $words[$word] + 1 : 1);
}
$in_list = implode(', ', array_keys($words));  //  'hi', 'how', 'are', 'you'

假设一个字数的多个副本仅为 1。

对于重复计数的递增,事情变得更加混乱。

根据您的解析代码:

$words = array();
preg_match_all('/<[^>]++>|[^<>\s]++/', $sent, $tokens);
foreach($tokens as $token) {
    $words[$word] = (isset($words[$word]) ? $words[$word] + 1 : 1);
}
$in_list = implode(', ', array_keys($words));
echo $in_list;

【讨论】:

  • @programmingfreak - while(...) 和 $word=... 需要替换为您的代码以将句子拆分为“单词”。
  • 我不明白你能告诉我你的意思吗?请问我应该把代码放在哪里
  • 我又加了一个例子。
【解决方案3】:

我不确定我是否理解这个问题,但我会试一试,如果这不是您要的,请告诉我(英语不是我的第一语言)。

PHP

<?php
// Connects to DB
$conn = mysqli_connect ( 'server', 'username', 'password', 'db');

if ( isset ( $_GET['sentence'] ) ) {

  // Sets the table var
  $table = "";

  // Prevents SQL Injection
  $sentence = mysqli_real_escape_string ( $conn, $_GET['sentence'] );

  // Splits the sentence inputted by the user into an array of individual words
  $wordArr = explode (  " ", $sentence );

  // For loop to execute the SQL Query for each word
  for ( $x = 0; $x < count ( $wordArr ); $x++ ) {

    $word = $wordArr[$x];

    // SQL Query to information about the word (if it exists in the table) from DB
    $sqlFindWord = "SELECT * FROM `words` WHERE `word` = '$word'";

    // Executes the query
    $resultFindWord = mysqli_query ( $conn, $sqlFindWord );

    $resultFindWord = mysqli_fetch_assoc ( $resultFindWord );

    // If the word exists in the table...
    if ( $resultFindWord ) {

      $frequency = $resultFindWord['freq'] + 1;

      // SQL Query adds 1 to the word's frequency in the table
      $sqlUpdateFrequency = "UPDATE `words` SET `freq` = $frequency WHERE `word` = $word";

      // Executes SQL Query
      $resultUpdateFrequency = mysqli_query ( $conn, $sqlUpdateFrequency );

      // Adds word to HTML table
      $table .= "<tr><td>" . $word . "</td><td>" . $frequency . "</td></tr>";

    } else {

      // Word doesn't exist in the table, so it must be added with a frequency of 1
      $sqlAddWord = "INSERT INTO `words` (`word`, `freq`) VALUES ('$word', 1)";

      // Executes the query
      $resultAddWord = mysqli_query ( $conn, $sqlAddWord );

      // Adds word to the HTML table
      $table .= "<tr><td>" . $word . "</td><td>1</td></tr>";

    }
  }
}
?>

HTML

<form action="#" method="GET" validate="">
  <input type="text" placeholder="Enter A Sentence" name="sentence" required />
  <input type="submit" value="Submit Sentence" />
</form>
<table>
  <tr>
    <th>Word</th>
    <th>Freq</th>
  </tr>
  <?php echo $table; ?>
</table>

如果您对代码的任何部分有任何疑问,或者如果我误解了问题,请告诉我。

【讨论】:

    猜你喜欢
    • 2022-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多