簡體   English   中英

如何使用 PHP 和 html 檢查句子的 SQL 中單詞的出現

[英]How to check the occurrence of the words in the SQL of a sentence using PHP and html

我從用戶輸入中得到一個句子,然后將其切成單詞並將它們列在一個數組中。

之后,我想根據句子中的單詞數將此數組傳遞給 SQL 查詢,該查詢將分別檢查每個單詞的出現,然后返回數字。

第一部分是通過使用正則表達式完成的:

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

output是這樣的:

在此處輸入圖像描述

但是對於 SQL 查詢循環,我被卡住了。 我不知道從哪里開始我的數據庫表是這樣的:

在此處輸入圖像描述

我預期的 output 是這樣的:

在此處輸入圖像描述

PS:-我認為PHP代碼首先應該知道用戶輸入句子的長度,然后對其進行標記以將單詞傳遞給SQL循環查詢以單獨搜索。

$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)";

如果一個句子可以有一個單詞兩次,你想讓表格增加兩次嗎? 不管你是否想要,我可能會構建一個 hash 而不是一個數組:

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

嘗試這個。 我將逐步解釋代碼。

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

PHP 代碼高於 HTML 代碼

我們將sentenceresult變量設置為空。 我們將用戶輸入的內容存儲到變量句中。 結果將是 MySQL 的結果。

if (isset($_GET['sentence'])) {... }塊檢查網頁是否有名為sentence的查詢字符串。 如果我們收到了那個查詢字符串,那就做點什么。 否則什么都不做。

在該塊中,我們按順序執行此操作:

  • 將用戶提供的句子存儲在變量中
  • 使用你的 preg_match_all 方法來標記句子
  • 動態創建 SQL
  • 執行 SQL 並將 output 存儲在結果變量中

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'不存在,你會得到

+----+----------------------+
| 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功能來轉義特殊字符並使查詢更安全。

然后,我們將所有 select 查詢連接在一起,並使用implode function 在它們之間進行union all

一旦我們收到查詢回來,我們使用$mysqli->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。 我們一一遍歷記錄並發布令牌和頻率。 如前所述,那些沒有頻率的詞將顯示為零。

試試看。 另請注意,可以對此代碼進行其他幾項改進,但這只是一個開始。

我不確定我是否理解這個問題,但我會試一試,如果這不是你想要的,請告訴我(英語不是我的第一語言)。

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>

如果您對代碼的任何部分有任何疑問,或者我誤解了問題,請告訴我。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM