搭建一个基于PHP和MySQL的一言Hitokoto接口

为了方便提高Hitokoto一言API接口的高并发业务场景,可以把它的文本内容集成到数据库中,并将其部署到你的VPS抑或是阿里云RDS上。倘若该一言API服务部署在服务器上,开放服务器防火墙3306端口和授予MySQL外部连接权限即可。Win10本地环境中,本次利用到Navicat Premium 15(可同时连接MySQL、MariaDB、MongoDB、SQL Server、Oracle、PostgreSQL和SQLite数据库),链接到远端数据库并验证连通性,首先建立一个名为hitokoto的数据库,数据表名同上。

简言

数据库名称和数据表的名字都叫hitokoto。表中有三个字段,分别为id(int类型,长度11,非空/NULL,主键), is_display(int类型,长度11), hitokoto(varchar类型,长度255),其中id为自增主键,is_display默认值为0。
创建接口,需要实现以下逻辑:随机返回一句话,并且返回的这句话与上次请求的结果不相同。设置一个is_display字段,用来保存调用状态,如果其value=1,说明上次刚刚被调用,反之亦然。在这一次调用时,随机返回除了上一次调用过的结果之外的句子,然后将上一次调用结果中的is_display的值改为0,将这次请求结果的is_display的值改为1。后端代码应用到前端,使用Ajax来发送与处理请求。

后端

hitokoto.php代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<?php
$sql_server = "MySQL服务器域名或者IPv4地址";
$sql_user = "root";
$sql_pass = "**";
$sql_dbname = "hitokoto";

class dataBase {
public function connectSql($sql_server,$sql_user,$sql_pass,$sql_dbname) {
$conn = new mysqli("$sql_server","$sql_user","$sql_pass","$sql_dbname");
mysqli_set_charset($conn,"utf8");
date_default_timezone_set("PRC");
return $conn;
}

public function sqlQuery($sql,$conn) {
$sql_query = $conn->query($sql);
return $sql_query;
}

public function getHitokotos($sql,$conn) {
$data = $conn->query($sql);
$data_arrays = [];
while ( $data_array = $data->fetch_array( MYSQLI_ASSOC ) ) {
$data_arrays[] = $data_array;
}
return $data_arrays;
}

public function getTotal($sql,$conn) {
$data1 = $conn->query($sql);
$total = $data1->fetch_array();
$totals = $total[0];
return $totals;
}
}
$dataBase = new dataBase();
$conn = $dataBase->connectSql($sql_server,$sql_user,$sql_pass,$sql_dbname);

$sql_hitokoto = "SELECT * FROM hitokoto WHERE is_display != 1";
$sql_total = "SELECT COUNT(*) FROM hitokoto WHERE is_display != 1";

$hitokotos = $dataBase->getHitokotos($sql_hitokoto,$conn);
$total = $dataBase->getTotal($sql_total,$conn);

$rand = rand(0,$total-1);
$id = $hitokotos[$rand]['id'];

$sql_dislpay1 = "UPDATE hitokoto SET is_display = 0 WHERE is_display = 1";
$sql_dislpay2 = "UPDATE hitokoto SET is_display = 1 WHERE id = '$id'";

$display_query1 = $dataBase->sqlQuery($sql_dislpay1,$conn);
$display_query2 = $dataBase->sqlQuery($sql_dislpay2,$conn);

echo($hitokotos[$rand]['hitokoto']);
mysqli_close($conn);
?>

前端

首先要在合适的位置添加div标签<div id="hitokoto">,或者直接在某需要输出的HTML标签内部(如<p>等等)id="hitokoto"也可以。
JavaScript代码如下所示,用来发起Ajax请求:

1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
function showHitokoto() {
var xmlhttp;
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "https://kixcs.com/hitokoto.php", true);
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4) {
document.getElementById('hitokoto').innerHTML = xmlhttp.responseText;
}
}
xmlhttp.send();
}
window.onload = showHitokoto()//加载时自动执行

倘若博客主题使用了Pjax无刷新,例如Hexo框架的静态博客中可以全局的指定Pjax属性,还需要指定Pjax重载函数,有很多跟上面的相同。

1
2
3
4
5
6
7
8
9
10
<script>
var xmlhttp;
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "./hitokoto.php", true);
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4) {
document.getElementById('hitokoto').innerHTML = xmlhttp.responseText;
}
}
xmlhttp.send();