试试这个。我将逐步解释代码。
<?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 代码
我们将sentence 和result 变量设置为空。我们将用户输入的内容存储到变量句中。结果将是 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->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。我们一一遍历记录并发布令牌和频率。如前所述,那些没有频率的词将显示为零。
试试看。另请注意,可以对此代码进行其他几项改进,但这只是一个开始。