最近写了个简单的记事簿APP,大概率应该能顺利地拿下软著,这里简单记录一下部分内容的实现。
1. 注册、登录与修改密码
在进行用户信息的存储时,客户端使用轻量级的SqliteDB进行存储,而服务端使用MysqlDB进行存储,将其表都命名为user,二者在表结构上是一致的,其具体结构如下:
id | username | password | nickname | |
---|---|---|---|---|
用户唯一标识,由系统自动分配 | 用户名,由用户自己定义,同样具有唯一性 | 密码 | 昵称 | 邮箱 |
当用户进行登录操作时,考虑有两种方式进行账号密码的核验,一种方法是根据用户名所输入的用户名在数据库的user表中进行索引,当匹配到记录时,将其密码返回给客户端,与用户输入的密码进行比较,若不同则拒绝登录,否则登录成功;另一种方法是将用户输入的用户名和密码同时作为选择条件在user表中查找记录,若没有记录,则返回登录失败,否则登录成功。显然,第二种方式不仅比第一种方法安全,也更加方便(无论用户存在还是不存在,除了账号和密码匹配以外的情况一律拒绝登录)。
在访问数据库时,出于安全考虑,程序并不是直接访问数据库,而是通过访问php接口来进行数据库中的信息读取和存储,即程序中不包含任何数据库信息,数据传输过程中也没有任何涉及到服务端账号密码之类的内容。
以注册为例,其请求过程分别如下图所示。
由图可知,访问数据库是由服务端内部发起的,客户端并没有直接与数据库建立联系,而是通过PHP接口来进行数据传输,因此这样设计有利于服务端的安全性,同时用户所使用的客户端处理的信息也有所简化,即写入和读取数据库内容的操作也由服务端来处理,客户端只需知道是否能够登录成功即可。
同理,邮箱验证码的发送与验证也有一个PHP接口参与,其具体过程如下图所示。
2. 记事簿的基本操作
记事簿的内容中由标题,日期以及正文组成,将其表命名为note,在数据库中存储记事簿的表结构可以确定如下:
id | username | title | date | content |
---|---|---|---|---|
记事簿唯一标识,由系统自动分配 | 用户名,由用户自己定义,同样具有唯一性 | 记事簿标题 | 记事簿最后修改(创建)日期 | 记事簿正文内容 |
考虑到用户在记事簿中可能会输入emoji表情等宽字符,而常用的UTF8编码最大字符长度为3字节,因此需要对于note表中的编码集进行修改,使其支持大于3字节的字符。目前来说,最佳的选择是utf8mb4字符集,其能支持的最大字符长度为4字节,能够处理emoji等大多数宽字符,不过utf8mb4字符集仅在Mysql的5.5.3版本以后才支持。为了支持emoji表情等宽字符,对数据库中的字符集进行修改,修改结果如下图所示。
而对于用户插入的图片,除了使用超链接的形式表达以外,可以考虑使用base64编码的方法将图片转成字符串的形式后,和其他文本内容一同存储在数据库中。当文本内容和图片base64编码下的字符串混合在一起时,如何区分是用户输入的内容还是图片编码的一部分,是需要考虑的一点。
对于一张图片,假设其base64编码后产生的字符串为$s$,借鉴HTML语言中使用类似于</ p>的形式来表达的方法,将字符串$s$插入至数据库之前,可在其前后加入标记符号,以表达字符串$s$是一张图片的base64编码。例如,本程序中定义的形式如下表达式(1)所示。
$$ \sigma p{\rm{ }} + {\rm{ }}no{\rm{ }} + {\rm{ }}\sigma {\rm{ }} + {\rm{ }}length{\rm{ }}of{\rm{ }}s{\rm{ }} + {\rm{ }}\sigma {\rm{ }} + {\rm{ }}s $$
当从数据库中取出记事簿内容时,对上述表达式进行解码,其具体规则就是确定$s$,显然当发现上述表达式时,$s$为第二个$\sigma$后面$n$位字符($n=length(s)$),得到了$s$后,直接逆转换成图片进行显示即可。
对于删除功能,由于在主界面中用户进行删除时其记事簿实际上并没有从数据库中删除,而达到其效果有两种实现方法。一种是创建一个表(例如,表名为“bin”),用于存储用户在主界面中删除的记事簿,则用户在主界面进行删除时将在note表中对应的记事簿删除,然后将其移动至bin表,则主界面中显示的为note表中属于该用户的记事簿,而回收站显示bin表中属于该用户的记事簿。同理,进行恢复操作时,就是上述删除过程的逆过程,而彻底删除就是从bin表中删除;另一种方式是在修改note表结构,在note表中增加一列作为笔记簿是否被用户在主界面中删除的标记,例如当增加名为“discard”的一列时,默认情况下其值为0,当用户在主界面中删除记事簿时,则对应记录的discard值变为1,而当用户彻底删除时,则从表中删除记录。如此一来,主界面中显示属于该用户且discard的值为0的记事簿,回收站显示属于该用户且discard值为1的记事簿,这样设计有利于消除数据库设计上的冗余性。
评论(0)