附录2 . 学习PHP常用的英文单词

最后更新于:2022-04-02 00:23:22

Hypertext Preprocessor Java html script API office word html web server windows back next cancel folder choose setup install administrator/root/admin finish stop start config log/logs help quit module service port Explorer linux mac os studio zend studio eclipse notepad note pad vim gvim down download code info phpinfo dollar var/variable echo int integer bool boolearn string title float double if else null result dump set unset object array resource call back callback type is get numeric mixed auto check define line method class version dir name space include user my test demo password text get post submit value input body address file request fire fox bug action software content home role length protocol interface status time connection remote switch case default break date while go to goto count table continue declare function plus cookie session static match max min rand year uninx timezone seconds minutes hours day weekday month mirco first end tags replace encoding pop push list each key prev reset current sort regex read create write move copy data exists clear cache able lock seek close group own owner path base build parse discuz upload size limit memory enabled disabled progress temp done error field style png jpeg/jpg gif header width height ascii display report level notice warning all core STRICT DEPRECATED trigger mysql command monitor or oracle Copyright engine index charset execute fetch row assoc db database edit delete update alter modify change add unsigned ZEROFILL enum stamp union order goods left right join from inner outer shop cms system manger money access agent token thread thread-safe throw video
';

附录1. 版权声明

最后更新于:2022-04-02 00:23:19

## 版权声明 本书的版权归本书的贡献者所有。 您可以随意转载和传播,但必须注明来源。来源请声明:《7天学会PHP》。 我们保留最终追究的权力。 ## 免责声明 由于我们是一本开源开放,共同参与写作的书,我们没法做到100%的审核。书中的部份代码和说明,部份贡献者(开发者)如果侵犯了您的权利。 请邮件给我们:3wfindme@gmail.com 我们将在24小时进行删除 ## 本书贡献者 主要作者:`李文凯 bob` 欢迎加入我们共同创作本书、提出意见,让更多的初学者受益,让大学和工作迷茫的人,不再迷茫!
';

16.6.7 项目安装模块讲解

最后更新于:2022-04-02 00:23:17

##安装功能说明 我们在电脑上安装软件的时候,点击下一步调整一些配置选项软件就安装成功了。 不需要非常高深的计算机技术即可让普通人完成安装。 我们在真正的商业型产品中也需要做完整的安装过程: 1. 极为方便普通用户 2. 看起来特别专业 3. 操作起来简单提高效率 我们的PHP的论坛、商城、OA、微信平台都可以做这样的安装包,普通用户下载我们的安装包后。几步就可以开始使用我们的服务。 这样对用户和对开发人员都好。 ##安装相关基本概念 | 概念 | 说明 | | -- | -- | | 安装目录 | 通常在install目录下 | | 安装锁 | 通常为install.lock,有这个文件就是安装过,无这个文件就是未安装 | | PHP扩展模块判断 | mysqli模块没有就无法操作数据库,我们则拒绝用户继续安装 | | 目录权限判断 | 我们会写入install.lock或者一些临时文件,若某些目录没有写入修改权限则无法安装成功 | | 版本权限判断 | 如果是php4.x版本想安装我们的应用,我们会提醒用户PHP版本太低无法安装 | |超级管理员 | 初使的最高管理员,可以管理后台,方便用户管理,安装时即设置 | | 初始数据库结构|初始的数据库我们是将开发的数据库清空后,打开.sql文件,分行执行,向数据库写入创建表的语句和初始信息 | > 注:所有的代码文件实例请下载我们的安装包。查看install目录。 ##安装核心步骤说明 1. 打开网站。打开网站若不存在install.lock文件则识为未安装 2. 存在安装锁文件install.lock则禁止用户执行安装 3. 展示安装协议 4. 检测操作系统和PHP版本,是否版本准许。若版本不准许则不展示下一步。 5. 判断权限是否具备相关目录的写入权限和PHP的图像、数据库模块权限,若不具备相关权限则不显示下一步。 6. 输入服务器地址、数据库信息等配置文件,按照输入的信息连接数据库 7. 输入管理员信息 8. 将基本信息准备好,导入指定数据库数据表内容 9. 导入成功,创建一个空文件install.lock ##install.lock文件判断 在/common/common.php文件中有这么一段: ~~~ //项目安装 if(!file_exists('install.lock')) { header('location:install/index.php'); exit; } ~~~ 若文件不存在则跳转至header目录。停止继续向下执行 /install/top.php文件中有这一段: ~~~ if(file_exists('../install.lock')){ header('content-type:text/html; charset=utf-8;'); exit('网站已经被安装过了,如果需要重新安装网站,请删除 /install.lock 文件'); } ~~~ 若存在install.lock文件禁止执行安装步骤。 ##判断版本 获得操作系统版本 ~~~ function userOS(){ //$user_OSagent = $_SERVER['HTTP_USER_AGENT']; $user_OSagent = PHP_OS; if($user_OSagent) { $visitor_os = $user_OSagent; } else { $visitor_os = '其它'; } return $visitor_os; } ~~~ 获得PHP的版本号: ~~~ echo PHP_VERSION ~~~ ##判断目录权限 判断目录写入权限的自定义函数: ~~~ function iswriteable($file){ if(is_dir($file)){ $dir=$file; if($fp = fopen("$dir/test.txt", 'w')) { fclose($fp); unlink("$dir/test.txt"); $writeable = 1; }else{ $writeable = 0; } }else{ if($fp = fopen($file, 'a+')) { fclose($fp); $writeable = 1; }else { $writeable = 0; } } return $writeable; } ~~~ 判断模块权限: ~~~ function_exists('mysqli_connect') ~~~ 如果存在相关函数,则存在相关模块。 ##修改配置文件 相关代码参考本书:《8.11 修改置文件的实验》 ##数据库导入代码 将创建库的SQL语句准备好,创建数据库发送创建数据库的相关命令即可。 ~~~ //执行数据库导入 include '../config/database.php'; //新建数据库 $link = mysqli_connect(DB_HOST, DB_USER, DB_PASS); if(mysqli_get_server_info($link) > '4.1') { mysqli_query($link, "CREATE DATABASE IF NOT EXISTS `".DB_NAME."` DEFAULT CHARACTER SET ".DB_CHARSET); } else { mysqli_query($link, "CREATE DATABASE IF NOT EXISTS `".DB_NAME."`"); } if(mysqli_connect_errno($link)){ exit('数据库不存在'); } mysqli_close($link); ~~~ 导入数据库打开apple_bbs.sql准备好的SQL文件,这个SQL文件中每一行的行尾以;NoAlike结尾。 我们使用explode将sql文件切割成一个数组,循环数组的每一行完成数据的导入。 ~~~ $sql=file_get_contents('apple_bbs.sql'); $conn=mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME); if(mysqli_errno($conn)){ exit(mysqli_error($conn)); } mysqli_set_charset($conn, DB_CHARSET); $arr=explode(';NoAlike;',$sql); foreach($arr as $val){ if(!empty($val)) { $Nval = str_replace('bbs_', DB_PREFIX, $val); $result = mysqli_query($conn, $Nval); if($result){ $sql = '数据库导入成功'; }else{ $sql = '数据库导入失败'; } } } mysqli_close($conn); ~~~ > 注:所有的代码文件实例请下载我们的安装包。查看install目录。
';

16.6.6 回帖功能讲解

最后更新于:2022-04-02 00:23:15

##回帖功能 模板所在位置: `/theme/default/detail.html` PHP页面 `detail.php` ##页面功能说明 detail.php页面可以展示、也可以回复,还能够实现删贴、高亮、精华、屏蔽等操作。 ####操作流程 1. 加载基础 2. 判断是否 3. 判断get或者post传入的类型是什么 4. 若是回复则走回复流程,若是删除、精华、屏蔽则走对应的流程 5. 将回复内容和SQL语句准备完成,并写入数据库 6. 失败报错 7. 成功则提示成功,送金币跳转回原贴地址 ##回贴、删除、置顶功能流程图 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-23_5629a9b9d1600.png) ##整体代码演示 ~~~ 禁止非法操作'; $url = $_SERVER['HTTP_REFERER']; $style = 'alert_error'; $toTime = 3000; include 'notice.php'; } $Id=$_REQUEST['id']; //保存帖子回复 if($_POST['replysubmit']) { //判断用户是否登录 if(!$_COOKIE['uid']){ $notice='抱歉,您尚未登录'; include 'close.php'; exit; } $tid = $Id; //跟帖时记录贴子ID $authorid = $_COOKIE['uid']; //发布人ID $content = strMagic($_POST['message']); //内容 $addtime = time(); //发表时间 $addip = ip2long($_SERVER['REMOTE_ADDR']); //发布人IP $classId = $_POST['classid']; //类别ID $n='first, tid, authorid, content, addtime, addip, classid'; $v='0, '.$tid.', '.$authorid.', "'.$content.'", '.$addtime.', '.$addip.', '.$classId.''; $result = dbInsert('details', $n, $v); if(!$result) { $msg = '回复失败,请联系管理员'; $url = $_SERVER['HTTP_REFERER']; $style = 'alert_error'; $toTime = 3000; include 'notice.php'; exit; }else{ $money = REWARD_H; //回帖赠送积分 $result = dbUpdate('user', "grade=grade+{$money}", 'uid='.$_COOKIE['uid'].''); //更新帖子的回复数量[replycount] $result = dbUpdate('details', 'replycount=replycount+1', 'id='.$tid.''); //更新版块表的回复数量[replycount] $result = dbUpdate('category', 'replycount=replycount+1', 'cid='.$classId.''); //header('location:detail.php?id='.$Id); $msg = '帖子回复成功'; $url = 'detail.php?id='.$Id; $style = 'alert_right'; $toTime = 3000; include 'notice.php'; $msg = '回帖赠送'; include 'layer.php'; exit; } } //点击帖子时访问次数加1 $result = dbUpdate('details', 'hits=hits+1', 'id='.$Id.' and isdel=0 and first=1'); if(!$result) { $msg = '您浏览的帖子不存在或已被删除'; $url = $_SERVER['HTTP_REFERER']; $style = 'alert_error'; $toTime = 3000; include 'notice.php'; } //读取帖子信息 $TiZi = dbSelect('details','*','id='.$Id.' and isdel=0 and first=1','',1); $authorid = $TiZi[0]['authorid']; //作者ID $Title = $TiZi[0]['title']; //标题 $Content = $TiZi[0]['content']; //内容 $Addtime = getFormatTime($TiZi[0]['addtime']); //发布时间 $classId = $TiZi[0]['classid']; //版块ID $Replycount = $TiZi[0]['replycount']; //回复数量 $Hits = $TiZi[0]['hits']; //点击数量 $Elite = $TiZi[0]['elite']; //精华 $Rate = $TiZi[0]['rate']; //所需积分数量 //读取上一条 $top = dbSelect('details','id','id>'.$Id.' and isdel=0 and first=1','id desc',1); if($top) { $topid=$top[0]['id']; }else{ $topid=false; } //读取下一条 $down = dbSelect('details','id','id<'.$Id.' and isdel=0 and first=1','id desc',1); if($down){ $downid = $down[0]['id']; }else{ $downid = false; } //读取导航索引 $category = dbSelect('category','cid,classname,parentid,compere','parentid<>0 and cid='.$classId.'','',1); if($category) { $smallName = $category[0]['classname']; $smallId = $category[0]['cid']; $BanZhu = $category[0]['compere']; $parentCategory = dbSelect('category','cid,classname','cid='.$category[0]['parentid'].'','',1); if($parentCategory) { $bigName=$parentCategory[0]['classname']; $bigId=$parentCategory[0]['cid']; }else{ $msg = '非法操作'; $url = $_SERVER['HTTP_REFERER']; $style = 'alert_error'; $toTime = 3000; include 'notice.php'; exit; } }else{ $msg = '非法操作'; $url = $_SERVER['HTTP_REFERER']; $style = 'alert_error'; $toTime = 3000; include 'notice.php'; exit; } //读取会员信息 $User = dbSelect('user','username,email,udertype,regtime,lasttime,picture,autograph,grade','uid='.$authorid.'','',1); if($User) { $U_sername = $User[0]['username']; $E_mail = $User[0]['email']; $U_dertype = $User[0]['udertype']; $R_egtime = formatTime($User[0]['regtime'],false); $L_asttime = formatTime($User[0]['lasttime'],false); $P_icture = $User[0]['picture']; $A_utograph = $User[0]['autograph']; $G_rade = $User[0]['grade']; } //该主题下的所有回复数量 $TZCount = dbFuncSelect('details','count(id)','tid='.$Id.' and isdel=0 and first=0'); $zCount = $TZCount['count(id)']; $linum = 10; $Lpage = empty($_GET['page'])?1:$_GET['page']; //循环帖子回复信息 $select = 't.id as id,t.isdisplay as isdisplay,t.authorid as authorid,t.content as content,t.addtime as addtime,t.addip as addip,t.isdel as isdel,t.elite as elite,u.username as username,u.email as email,u.udertype as udertype,u.regtime as regtime,u.lasttime as lasttime,u.picture as picture,u.autograph as autograph,u.grade as grade'; $HTiZi = dbDuoSelect('details as t','user as u',' on t.authorid=u.uid',null,null,$select,'t.tid='.$Id.' and t.isdel=0 and t.first=0','t.id asc', setLimit($linum)); $title = $Title.' - '.WEB_NAME; $ggg = 'iPhone 游戏软件分享区'; //查找版主或管理员 $NBanZhu = explode(',',$BanZhu); if(in_array($_COOKIE['uid'], $NBanZhu)) { $GuanLi=true; }else{ if($_COOKIE['udertype']) { $GuanLi=true; } } //给帖子付款 if(!empty($_POST['paysubmit'])) { //判断用户是否登录 if(!$_COOKIE['uid']) { $notice='抱歉,您尚未登录'; include 'close.php'; exit; } foreach($_POST['oidarr'] as $key=>$val) { $nval=explode(',',$val); //将order表中的ispay更新为1 $res = dbUpdate('order', 'ispay=1', 'oid='.$key.''); //扣钱 $res = dbUpdate('user', 'grade=grade-'.$nval[1].'', 'uid='.$_COOKIE['uid'].''); //给作者加钱 $res = dbUpdate('user', 'grade=grade+'.$nval[1].'', 'uid='.$nval[0].''); } header('location:detail.php?id='.$Id); exit; } //删除未购买的帖子 if(!empty($_POST['delsubmit'])) { //判断用户是否登录 if(!$_COOKIE['uid']) { $notice='抱歉,您尚未登录'; include 'close.php'; exit; } $arrOid = array_keys($_POST['oidarr']); $NarrOid = join(',',$arrOid); $result = dbDel('order', 'oid in('.$NarrOid.')'); header('location:detail.php?id='.$Id); exit; } //购买帖子,点击及加入订单表 if(!empty($_GET['pay'])) { //判断用户是否登录 if(!$_COOKIE['uid']) { $notice='抱歉,您尚未登录'; include 'close.php'; exit; } //查询订单表中是否有这个购买记录 $select = 't.title as title,t.authorid as authorid,o.oid as oid,o.tid as tid,o.uid as uid,o.rate as rate'; $IsOrder = dbDuoSelect('order as o','details as t',' on o.tid=t.id',null,null,$select,'o.uid='.$_COOKIE['uid'].' and t.id='.$Id.'','o.oid asc',1); if(!$IsOrder) { //如果没有购买记录,加入订单表 $Oresult = dbInsert('order', 'uid,tid,rate,addtime,ispay', $_COOKIE['uid'].','.$Id.','.$Rate.','.time().',0'); } //读取这个用户还没有付款的记录 $OrderList = dbDuoSelect('order as o','details as t',' on o.tid=t.id',null,null,$select,'o.uid='.$_COOKIE['uid'].' and o.ispay=0','o.oid asc'); $allpay = dbFuncSelect('order','sum(rate ) as zpay','uid='.$_COOKIE['uid'].' and ispay=0'); } //检查当前浏览用户是否已付费 $MyOrder = dbSelect('order','*','uid='.$_COOKIE['uid'].' and ispay=1 and tid='.$Id.'','oid asc',1); if($GuanLi){ //删除,放入回收站 if(!empty($_GET['del'])){ $result = dbUpdate('details', "isdel=1", 'id='.$Id.''); header('location:index.php'); } //置顶 if(!empty($_GET['istop'])){ $result = dbUpdate('details', "istop=1", 'id='.$Id.''); header('location:detail.php?id='.$Id); } //高亮 if(!empty($_GET['style'])){ $result = dbUpdate('details', "style='red'", 'id='.$Id.''); header('location:detail.php?id='.$Id); } //精华 if(!empty($_GET['elite'])){ $result = dbUpdate('details', "elite=1", 'id='.$Id.''); header('location:detail.php?id='.$Id); } //删除回帖,放入回收站 if(!empty($_GET['delht'])){ $result = dbUpdate('details', "isdel=1", 'id='.$_GET['hid'].''); header('location:detail.php?id='.$Id); } //回帖置顶 if(!empty($_GET['istopht'])){ $result = dbUpdate('details', "istop=1", 'id='.$_GET['hid'].''); header('location:detail.php?id='.$Id); } //回帖屏蔽 if(!empty($_GET['isdislpay'])){ $result = dbUpdate('details', "isdisplay=1", 'id='.$_GET['hid'].''); header('location:detail.php?id='.$Id); } } include template("detail.html"); ~~~
';

16.6.5 发帖功能讲解

最后更新于:2022-04-02 00:23:13

##发贴功能 模板所在位置: `/theme/default/addc.html` PHP页面 `addc.php` ####操作流程 1. 用户点击进入发贴页的时候,将所选版块的ID带上。URL示例如下:http://bbs.com/addc.php?classid=5。我们就可以知道用户是向哪个版块发贴。 2. 判断用户是否存在 3. 判断版块是否存在,如果不存在的话,插入的版块即非法。我们让用户发贴不能成功。 4. 展示导航,版块名等基本信息,渲染进入模板 5. 准本好要插入的基本信息,拼接SQL语句,并插入库 6. 判断是否写入成功 7. 成功给用户金币(积分),跳转至贴子页 ####1. 判断用户是否登陆,未登陆不能发贴 ~~~ //包含公共组件 include './common/common.php'; //判断用户是否登录 if(!$_COOKIE['uid']) { $notice = '抱歉,您尚未登录,没有权限在该版块发帖'; include 'close.php'; exit; } ~~~ ####2.判断ID是否存在 ~~~ if(empty($_REQUEST['classid']) || !is_numeric($_REQUEST['classid'])) { $msg = '禁止非法操作'; $url = $_SERVER['HTTP_REFERER']; $style = 'alert_error'; $toTime = 3000; include 'notice.php'; } $classId = $_REQUEST['classid']; ~~~ ####3. 读取版块相关的基本信息 ~~~ $category = dbSelect('category','cid,classname,parentid','parentid<>0 and cid='.$classId.'','',1); if($category){ $smallName = $category[0]['classname']; $smallId = $category[0]['cid']; $parentCategory = dbSelect('category','cid,classname','cid='.$category[0]['parentid'].'','',1); if($parentCategory) { $bigName=$parentCategory[0]['classname']; $bigId=$parentCategory[0]['cid']; }else{ $msg = '非法操作'; $url = $_SERVER['HTTP_REFERER']; $style = 'alert_error'; $toTime = 3000; include 'notice.php'; exit; } }else{ $msg = '非法操作'; $url = $_SERVER['HTTP_REFERER']; $style = 'alert_error'; $toTime = 3000; include 'notice.php'; exit; } ~~~ ####4.准备发布内容 ~~~ $authorid = $_COOKIE['uid']; //发布人ID $title = strMagic($_POST['subject']); //标题 $content = strMagic($_POST['content']); //内容 $addtime = time(); //发表时间 $addip = ip2long($_SERVER['REMOTE_ADDR']);//发布人IP $classId = $_POST['classid']; //类别ID $rate = $_POST['price']; //帖子售价 $n = 'first, authorid, title, content, addtime, addip, classid, rate'; $v = '1, '.$authorid.', "'.$title.'", "'.$content.'", '.$addtime.', '.$addip.', '.$classId.', '.$rate.''; $result = dbInsert('details', $n, $v); ~~~ ##整体代码展示 ~~~ 禁止非法操作'; $url = $_SERVER['HTTP_REFERER']; $style = 'alert_error'; $toTime = 3000; include 'notice.php'; } $classId = $_REQUEST['classid']; //读取导航索引 $category = dbSelect('category','cid,classname,parentid','parentid<>0 and cid='.$classId.'','',1); if($category){ $smallName = $category[0]['classname']; $smallId = $category[0]['cid']; $parentCategory = dbSelect('category','cid,classname','cid='.$category[0]['parentid'].'','',1); if($parentCategory) { $bigName=$parentCategory[0]['classname']; $bigId=$parentCategory[0]['cid']; }else{ $msg = '非法操作'; $url = $_SERVER['HTTP_REFERER']; $style = 'alert_error'; $toTime = 3000; include 'notice.php'; exit; } }else{ $msg = '非法操作'; $url = $_SERVER['HTTP_REFERER']; $style = 'alert_error'; $toTime = 3000; include 'notice.php'; exit; } //发布帖子 if($_POST['topicsubmit']) { $authorid = $_COOKIE['uid']; //发布人ID $title = strMagic($_POST['subject']); //标题 $content = strMagic($_POST['content']); //内容 $addtime = time(); //发表时间 $addip = ip2long($_SERVER['REMOTE_ADDR']);//发布人IP $classId = $_POST['classid']; //类别ID $rate = $_POST['price']; //帖子售价 $n = 'first, authorid, title, content, addtime, addip, classid, rate'; $v = '1, '.$authorid.', "'.$title.'", "'.$content.'", '.$addtime.', '.$addip.', '.$classId.', '.$rate.''; $result = dbInsert('details', $n, $v); $insert_id = dbSelect('details','id','title="'.$title.'"','id desc',1); $insertId = $insert_id[0]['id']; if(!$result){ $msg = '帖子发表失败,请联系管理员'; $url = $_SERVER['HTTP_REFERER']; $style = 'alert_error'; $toTime = 3000; include 'notice.php'; exit; }else{ $money = REWARD_T; //发帖赠送积分 $result = dbUpdate('user', "grade=grade+{$money}", 'uid='.$_COOKIE['uid'].''); //更新版块表的主题数量[Motifcount](跟帖是回复数量[eplycount])和最后发表[lastpost] $last = $insertId.'+||+'.$title.'+||+'.$addtime.'+||+'.$_COOKIE['username']; $result = dbUpdate('category', 'motifcount=motifcount+1, lastpost="'.$last.'"', 'cid='.$classId.''); $msg = '帖子发表成功'; $url = 'detail.php?id='.$insertId; $style = 'alert_right'; $toTime = 3000; include 'notice.php'; $msg = '发帖赠送'; include 'layer.php'; exit; } } $OnMenu = dbSelect('category','cid,classname','cid='.$classId.' and ispass=1','orderby desc,cid desc'); if(!$OnMenu) { $msg = '没有找到该版块'; $url = $_SERVER['HTTP_REFERER']; $style = 'alert_error'; $toTime = 3000; include 'notice.php'; }else{ $OnCid = $OnMenu[0]['cid']; $OnCname = $OnMenu[0]['classname']; } $title = '发表帖子'.$OnCname.' - '.WEB_NAME; $menu = WEB_NAME; include template("addc.html"); ~~~
';

16.6.4 用户注册、登陆功能讲解

最后更新于:2022-04-02 00:23:10

## 注册功能 模板所在位置: `/theme/default/reg.html` PHP页面 `reg.php` > 需要完成的功能点: 1 对输入项要进行魔术转义,防止SQL注入; 2 验证邮箱格式; 3 验证密码:长度,并校验两次输入是否一致; 4 校验数据库中是否存在改用户名; 5 校验图片验证码输入是否正确; 6 若全部校验通过则创建用户,并自动登录,登陆状态使用`Cookie`记录; 7 注册成功,赠送积分; ~~~ 用户名长度错误:用户名由 3 到 12 个字符组成'; } //判断数据库里是否存在这个用户名 $exists = dbSelect('user','uid', 'username="'.$uname.'"','uid desc',1); if($exists) { $alterNotice = true; $msgArr[] = '用户名已存在'; } //验证密码长度 if(stringLen($upass)) { $alterNotice = true; $msgArr[] = '密码长度错误:由 3 到 12 个字符组成'; } //验证两次密码是否一致 if(str2Equal($upass, $urpass)) { $alterNotice = true; $msgArr[] = '错误:两次密码不一致'; } //验证email if(checkEmail($umail)) { $alterNotice = true; $msgArr[] = '错误:邮箱不合法'; } //判断验证码 if(checkVerify($pyzm, $_SESSION['code'])) { $alterNotice = true; $msgArr[] = '验证码输入错误'; } //验证是否需要显示提示信息 if($alterNotice) { $msg = join('
', $msgArr); include 'notice.php'; exit; } //创建用户 $money = REWARD_REG; $n = 'username, password, email, udertype, regtime, lasttime, regip, grade'; $v = "'$uname', '".md5($upass)."', '$umail', 0, ".time().", ".time().", ".ip2long($_SERVER['REMOTE_ADDR']).", ".$money; $result = dbInsert('user', $n, $v); if(!$result) { $msg = '注册失败,请联系管理员'; include 'notice.php'; }else{ //注册成功后自动登录 $result = dbSelect('user', 'uid,username,udertype,picture,grade', 'username="'.$uname.'" and password="'.md5($upass).'"', 'uid desc', 1); setcookie('uid',$result[0]['uid'],time()+86400); setcookie('username',$result[0]['username'],time()+2592000); setcookie('udertype',$result[0]['udertype'],time()+86400); setcookie('picture',$result[0]['picture'],time()+86400); setcookie('grade',$result[0]['grade'],time()+86400); $msg = '感谢您的注册,现在将以会员身份登录站点'; $url = 'index.php'; $style = 'alert_right'; include 'notice.php'; $msg = '注册赠送'; include 'layer.php'; } }else{ include template("reg.html"); } ?> ~~~ ## 用户登陆 PHP页面 `login.php` > 需要完成的功能点: 1 自动登陆功能,通过设置`Cookie`的过期时间来验证是否使用了自动登陆,有效期为30天。若浏览器`Cookie`被清除则自动失效; 2 验证登陆账号是否被管理员从后台锁定; 3 记录用户最后登陆时间; ~~~ 登录失败,用户名或密码错误'; $url = $_SERVER['HTTP_REFERER']; $style = 'alert_error'; $toTime = 3000; include 'notice.php'; }else{ if($result[0]['allowlogin']) { $msg = '您的账号已经被锁定,请联系管理员'; $url = $_SERVER['HTTP_REFERER']; $style = 'alert_error'; $toTime = 3000; include 'notice.php'; exit; } $money = REWARD_LOGIN; if(formatTime($result[0]['lasttime']) Cookie 时间设置为当前时间-1,视为立即失效; ~~~ 您已退出站点,现在将以游客身份转入退出前页面'; $url = 'index.php'; $style = 'alert_right'; $toTime = 3000; include 'notice.php'; ~~~ 退出成功后,跳转到首页。
';

16.6.3 模板引擎讲解

最后更新于:2022-04-02 00:23:08

## 什么是模版引擎? > 百度百科的解释: 为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。 是不是听起来很晕? > 用一句白话解释: 就是把静态页面中特定的一些标记(字符串)替换成最终需要的PHP标签; > 好处: 可以让(网站)程序实现界面与数据分离,这就大大提升了开发效率,好的设计也使得代码重用变得更加容易。 ## 编写自己的模板引擎 > 这里需要注意两点: 1 字符串替换,将`{` 和 `}` 分别替换成 PHP 标签 `` 2 为提升程序执行效率,使用模板缓存; ~~~ filemtime($comFile)) { tplParse($tmpFile,$comFile); } return $comFile; } function tplParse($tFile,$cFile){ $fileContent=file_get_contents($tFile); $fileContent=preg_replace_callback("/^(\xef\xbb\xbf)/", function($r){}, $fileContent); $fileContent=preg_replace_callback( "/\<\!\-\-\s*\\\$\{(.+?)\}\s*\-\-\>/is", function($r) { return str_replace('\"', '"', ''); }, $fileContent ); $fileContent=preg_replace_callback( "/\{(\\\$[a-zA-Z0-9_\[\]\\\ \-\'\,\%\*\/\.\(\)\>\'\"\$\x7f-\xff]+)\}/s", function($r) { return str_replace('\"', '"', ''); }, $fileContent ); $fileContent=preg_replace_callback( "/\\\$\{(.+?)\}/is", function($r) { return str_replace('\"', '"', ''); }, $fileContent ); $fileContent=preg_replace_callback( "/\<\!\-\-\s*\{else\s*if\s+(.+?)\}\s*\-\-\>/is", function($r) { return str_replace('\"', '"', ''); }, $fileContent ); $fileContent=preg_replace_callback( "/\<\!\-\-\s*\{elif\s+(.+?)\}\s*\-\-\>/is", function($r) { return str_replace('\"', '"', ''); }, $fileContent ); $fileContent=preg_replace_callback( "/\<\!\-\-\s*\{else\}\s*\-\-\>/is", function($r) { return ""; }, $fileContent ); for($i=0; $i<5; ++$i){ $fileContent = preg_replace_callback( "/\<\!\-\-\s*\{loop\s+(\S+)\s+(\S+)\s+(\S+)\s*\}\s*\-\-\>(.+?)\<\!\-\-\s*\{\/loop\}\s*\-\-\>/is", function($r) { return str_replace('\"', '"', ''.$r[3].') { ?>'.$r[4].''); }, $fileContent ); $fileContent = preg_replace_callback( "/\<\!\-\-\s*\{loop\s+(\S+)\s+(\S+)\s*\}\s*\-\-\>(.+?)\<\!\-\-\s*\{\/loop\}\s*\-\-\>/is", function($r) { return str_replace('\"', '"', ''.$r[3].''); }, $fileContent ); $fileContent = preg_replace_callback( "/\<\!\-\-\s*\{if\s+(.+?)\}\s*\-\-\>(.+?)\<\!\-\-\s*\{\/if\}\s*\-\-\>/is", function($r) { return str_replace('\"', '"', ''.$r[2].''); }, $fileContent ); } $fileContent = preg_replace_callback( "##i", function($r) { return ''; }, $fileContent ); file_put_contents($cFile,$fileContent); return true; } ~~~ ## 如何使用自己的模板引擎? > 公共文件`/common/common.php`中已经载入了模版引擎函数库,并指定了模板风格; > 在 `/config/config.php` 中通过修改 `define('TPL_SKIN', 'theme/default');` 的值来,改变应用的模版风格(确保模板风格已经存在) ### 一 创建模板文件时使用的基本语法 #### 1 `echo` 输出变量: `{$title}` #### 2 `if` 判断: `{if $bigid}` ... `{else}` ... `{/if}` #### 3 `foreach` 循环: `{loop $LTsMenu $key $val}` `{$val['title']}` `{/loop}` #### 4 模版中使用函数 `${getUserName($val['compere'])}` #### 5 `include` 模板中包含模板: `{include header.html}` ### 二 使用模板 #### 1 分配变量 > 在包含模版前定义的PHP变量,都可以在模版中使用: `$title = '首页 - ' . WEB_NAME;` #### 2 包含模版文件 > 首先查找是否已经缓存,若未缓存 则替换标签后生成缓存文件。 `include template("index.html");`
';

16.6.2 公共文件的使用

最后更新于:2022-04-02 00:23:06

## 网站公共文件 /common/common.php 在 PHP 文件的顶部,使用 `include` 方式加载 `common/common.php` 文件,即可使用配置文件中定义的常量和函数库中的所有函数,并且使其校验过程在当前页面中生效。 网站公共文件的作用: > 设置 PHP的错误级别、网页字符集; > 用于校验站点是否已经安装; > 加载 config 中的所有文件、及 helpers 中的所有文件; > 初始化SESSION和网站的公共变量; > 网站的开启或关闭状态; > 校验禁止访问的IP地址; > 获取主导航的相关数据; ##公共文件包含关系 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-23_5629abb1dac8b.png) ##代码详解 ~~~ 1 基础配置(时区|魔术转译) > 2 静态资源 > 3 website > 4 模版引擎 > 5 奖励 ~~~ 网站安装过程中会重写该文件 (确保该文件具有可写权限) 的内容,无需手动修改配置。 ~~~ ';

16.6.1 项目目录结构说明

最后更新于:2022-04-02 00:23:03

项目目录结构和作用、及主要文件说明: | 目录 | 文件 | 描述 | | -- | -- | -- | | / | | 根目录 | | | install.lock | 安装后生成的锁文件 | | | index.php | 前台入口文件 | | | admin.php | 后台入口文件 | | ***/theme*** | | 模板目录 | | /theme/default | | 默认模板样式目录 | | ***/public*** | | 公共静态资源目录 | | /public/js | | JS文件目录 | | /public/css | | CSS文件目录 | | /public/images | | 图片文件目录 | | /public/ckeditor | | Ckeditor 网页编辑器目录 | | /public/admin | | 后台静态文件目录 | | ***/upload*** | | 上传文件目录 | | ***/install*** | | 安装文件目录 | | | apple_bbs.sql | 网站安装使用的数据库脚本 | | /install/images | | 安装程序静态资源目录 | | ***/common*** | | 公共文件目录 | | | admin_common.php | 后台公共文件,用于验证管理员登陆(SESSION)状态 | | | common.php | 网站公共文件,用于校验是否已经安装、加载数据库配置文件、网站基础配置配置文件、公共函数文件、初始化SESSION等等 | | ***/helpers*** | | 公共函数目录 | | | code.php | 验证码函数库 | | | fileupload.php | 文件上传函数库 | | | func.php | 公共函数库 | | | img.php | 图片处理函数库 | | | keywords.php | 热门搜索关键词数组 | | | mysql.php | Mysqli函数库 | | | mytpl.php | 模版引擎函数库 | | | page.php | 分页函数库 | | | user.php | 用户相关函数库 | | ***/config*** | | 配置文件目录 | | | config.php | 网站基础配置信息 | | | database.php | 数据库配置信息 | | ***/compiled*** | | 模板缓存文件目录 | | ... | ... | ... |
';

16.6 核心功能说明

最后更新于:2022-04-02 00:23:01

##项目实例下载地址 代码你可以登陆: http://down.phpxy.com/book/bbs.zip 下载论坛项目实例。
';

16.5 文件和代码规范

最后更新于:2022-04-02 00:22:59

## 通用注释 ### 1. 文件的注释通用样例(普通程序文件,类文件,函数文件,变量定义文件) ~~~ /** * XXXXX的文件 * * 功能1: xxx * 功能2: xxx * * @file $Source: /home/doc/php开发注释规范.md $ * @package core * @author Joy * @version $Id: php开发注释规范.txt,v 1.1 2014/03/04 20:37:46 Joy Exp $ * @link http://www.joychao.cc */ ~~~ * @package 是团队事先定义好的,在phpdocumentor里同一package的文件可以给出跟踪的链接。项目开发前需要对其定义。 * @link 行后面接的地址是程序开发文档的地址,因为我们目前没有在线的程序开发文档库,所以可不加。 注意注释的排版,左端保持对齐。 **说明:以上自动更新版本及文件名需要配置svn,具体请自行google 'SVN自动版本号'** ### 2. 普通函数注释 ~~~ /** * 获取头像地址 * * @author Joy * * @param string $imageName 图片文件名 * @param integer $size 大小 * * @return string */ function getAvatarUrl($imageName, $size = 80) { return sprintf(SITE_URL . '/service/images/cropped_%s/'.$imageName, $size); } ~~~ 顺序按照author、param、return来放,区块间空行。 ### 3. 程序段落注释 段落注释和逻辑注释使用如下方式 ~~~ /** * 1 如果$_GET['do']等于buy,则购买条码 */ if($_GET['do'] == 'buy') { // 1.1 验证用户提交变量是否合法 if($_POST['strCodeNum']) { } // 1.2 验证用户提交的码是否可以购买 // 1.3 .................. } // end if /** * 2 如果$_GET['do']等于list,显示用户选择的条码 */ if($_GET['do'] == 'list') { // 2.1 验证用户提交变量是否合法 if($_POST['strCodeNum']) { } // 2.2 验证用户提交的码是否可以购买 // 2.3 .................. } // end if ~~~
';

16.4 数据库表设计

最后更新于:2022-04-02 00:22:57

## 数据库设计:E-R图 ER图概念化地构建实体间关系的模型,这使得它们区别于数据库模型图。 ER图的理念是:项目所有参与者能理解ER图。 ER图由不同实体类型、关系、特性和类型构成。 实体是诸如用户的实际对象,有时更抽象,但必须有业务意义。 特性用于描述实体,关系用于实体之间: > (1)实体:现实世界中的事物; > (2)属性:事物的特性; > (3)联系:现实世界中事物间的关系。 实体集的关系有一对一、一对多、多对多的联系。 ## 数据库表及关系建立 1. 用户基本资料表 (bbs_user) ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e635acaa5.png) 2. IP黑名单表 (bbs_closeip) ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e63606dcd.png) 3. 友情链接表 (bbs_link]) ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e6362d451.png) 4. 论坛版块表 (bbs_category) ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-17_5621f8b2cc8b1.png) 5. 帖子信息表 (bbs_details) ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e6365e87a.png) 6. 帖子订单表 (bbs_order) ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e636b3b34.png)
';

16.3.7 金币奖励和消耗流程

最后更新于:2022-04-02 00:22:54

##积分业务说明 在需求部分我们讲解过积分(金币)的处理机制,机制如下: > 注册:赠送50积分; > 登陆:每天首次登陆赠送2积分; > 发帖:赠送2积分; > 回帖:赠送1积分; 通过这种金币(积分)业务的处理,能够极大的丰富市场运营部门的活动的可用性,增强用户粘性,让用户觉得自己的发贴和回贴是有价值和意义的。 例如:每天首次登陆送2个积分,就像京东商城的京豆一样。每天登陆,我可以送用户金豆,让用户经常访问,增加消息和购物的冲动。 ##增加金币流程图 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-23_56299a014348f.png) ##消耗金币流程图 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-23_56299a0155088.png) ##增加金币图例 在注册、回复成功和发贴成功等都会显示金币增加的相关图例。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e62f9adf4.png) ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e62dc8a8d.png) ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e62b2c5d7.png) ##展示金币贴图例 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-23_56299a0169c01.png)
';

16.3.6 版主业务流程

最后更新于:2022-04-02 00:22:52

##版主业务说明 在真实的项目中一个人很难将所有的工作全部完成。需要其他人来协助它。 例如在贴吧中可以指定某个热心网友为某个贴吧的小吧主,协助完成某些工作。 论坛中也是,管理员不可能某个版块都能够有足够的精力管理。因此,它可以指定某个用户为版主。 版主能够删掉这个版块的广告、违法信息屏蔽掉等功能。 因此,我们在这里也设计了一个版主功能。 ##添加版主流程 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-23_56299a00eceda.png) ##版主管理流程 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-23_56299a0109e96.png) ##图解版主管理 1.在后台管理界面中展示版本,在版主添写入写上用户的唯一ID ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e634b1dc1.png) 2.在前台展示这个用户为某个版块的版主 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e634e496d.png) 3.版主具有删除贴子等权限,而普通用户没有 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e63509455.png) 4.版主操作功能区展示 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e63564b5f.png)
';

16.3.5 版块管理流程

最后更新于:2022-04-02 00:22:50

##版块管理 在百度贴吧中,我们可以创建不同的贴吧。不同的贴吧,在论坛中就是版块。 不同的版块(贴吧)讨论不同的内容。 论坛的版本在结构上与贴吧略有一些小的不同: 1. 贴吧是单个层级的,没有父板块 2. 论坛分为大版块和小版块。而小版本添加时有一个父版块,也就是小版本是属于哪个大版块的。例如电脑版块下,有电脑维修和软件故障。 ##版块管理流程图 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-23_56299a00b8347.png) ##图解版本管理 1.如果是添加大版本在选择大版块是就不填写,这样就产生了一个大版本。如果我们是指定了大版块添加一个新版块,那么新版块就属于这个大版块 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e630bd64f.png) 2.展示版块 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e630d7e54.png)
';

16.3.4 回复流程

最后更新于:2022-04-02 00:22:47

##回复流程说明 我们遇到自己感兴趣的贴子,我们在下面可以的输入框中再次发表自己的观点和看法。 回贴成功后,系统可以针对这个用户加上对应的金币。 ##回复流程图 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-23_56299a00880af.png) 注意: 1. 选择贴子发起回复,判断用户是否登陆 2. 如果用户已登陆则直接发表成功,在发表的隐藏表单中放入这个贴子的ID 3. 用户没登陆进入登陆页,登陆成功后返回至原贴地址重新发起回复 ##图解回复流程 1.选择并查看贴子 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e62ee6ee5.png) 2.在贴子下面输入想要回复的内容 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e62f7a015.png) 3.回复成功并跳转回原贴地址 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e62f9adf4.png)
';

16.3.3 发贴流程

最后更新于:2022-04-02 00:22:45

##发贴说明 某个用户登陆成功,就可以使用某个用户发表贴子。 我们将贴子分为了普通贴和金币贴。 它们的区别: 1. 普通贴不需要花钱就可以看 2. 金币贴必须要使用注册时、每天登陆、回贴时获得的金币购买贴子后才能查看。 在发贴前,我们先要选择对应的版本,在所在贴块中点击发贴,写入对应的内容点击发表,发表成功。 ##流程图 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-23_56299a004f912.png) 说明: 1. 用户选择对应的版块后,点击发贴时传入了版块的ID 2. 在用户的发贴界面,将板块的ID放入了隐藏的表单中 3. 用户点发贴时,其实是相对应的 ##图解发贴流程 1.登陆成功后选择论坛中的相应版块,如:选择内核源码 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e62c70fc5.png) 2.点击发贴按钮发表贴子 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e62d9093c.png) 3.输入发贴内容、金币等 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e62daf11a.png) 4.贴子发表成功给用户虚拟金币奖励 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e62dc8a8d.png)
';

16.3.2 普通用户和管理员登陆流程

最后更新于:2022-04-02 00:22:43

##普通用户和管理员登陆的区别 我们在玩游戏的时候,会听到一个非常厉害的词:GM(游戏管理员)。游戏管理员,有一个专门的系统可以做到: 1. 删除用户 2. 封掉一个用户 3. 加一个新的游戏地图 4. 查看某些用户的聊天违规行为给出警告 ... ... 大家会发现,GM在游戏里面有。她与普通用户有一些区别,她有更高的操作权限。 在我们的论坛、办公管理系统、小说网站等系统中也会设计这一类特殊的用户。 这类特殊用户我们统一称之为:管理员。 论坛系统中普通用户和管理员的区别: | 权限 | 普通用户 | 管理员用户| | -- | -- | -- | | 注册 | 有 | 有 | | 登陆 | 有 |有| | 发贴 | 有 |有| | 回贴 | 有 |有| | 删自己贴 | 有 |有| | 删他人贴|无 |有 | | 删除用户| 版主有,用户没有 |有 | | 添加版主| 无 |有 | | 禁止用户|无 |有 | | 添加版本| 无 |有 | |修改网站名等基本信息|无 |有 | | 添加友情链接| 无 |有 | > 注意: 所在版块的普通用户中,有一种特殊用户叫版主用户。版主与普通用户的区别是:版主这种普通用户,能够管理自己所在版块的贴子。删除贴子、屏蔽贴子等。 ##普通用户、管理员登陆流程 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-23_56299a00081d9.png) 流程说明: 1. 用户输入信息后,显示用户名和密码是否正确,不正确返回重新输入 2. 用户名和密码正确则激活用户登陆的cookie 3. 用户如果是管理员展示示管理员入口;否则不显示,按普通用户操作 4. 管理员用户可进入管理员登陆页,进入前判断是否有进入该页的权限,如果没有则拒绝。 5. 输入管理员的帐号密码,进入验证通过则放行,否则拒绝通过。 ##图解登陆流程 **1.输入用户名和密码界面** ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e62b9c4c8.png) **2.普通用户登陆成功展示** ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e62bb1569.png) **3.管理员登陆成功展示** ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e62bc037e.png) **4.管理员点击管理中心进入后台展示页** ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e62bcf254.png) **5.后台界面展示** ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e62c2b3da.png)
';

16.3.1 用户注册流程

最后更新于:2022-04-02 00:22:41

##注册功能说明 用户注册是网上最最常见的一个功能,也是我们开始体验一个网站服务的开始。 例如:我们在京东、淘宝等网站注册了才能发贴。我们在微信、QQ等社交工具注册了才能够开始加好友开始聊天。 可以这么来讲,如果网站需要我们有个人信息,那么注册是我们体验一个互联网服务的开始的第一步。 而我们在开发过程当中,也会设计按照自己业务的注册流程。 注册流程可以不同,也可以相同。我们现在将本论坛的注册流程用流程图来表示: ##注册功能流程图 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e625470c8.png) > 注意:大家可以在《16.6 核心功能说明》中下载安装后,进一步体验每一步流程。 ##用图分解注册流程演示 第一步:点击注册按钮进入注册界面 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e62adaa7f.png) 第二步:在注册页输入注册信息 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e62b04ec5.png) 第三步:判断是否用户输入错误,如果输入错误显示错误信息 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e62b15e50.png) 第四步:如果输入信息无误,提示用户注册成功,并完成跳转。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-22_5628e62b2c5d7.png) *** 注: 请参考《16.4 数据库表设计》听用户表结构设计。对着流程完成用户注册代码的实现。
';

16.3 核心业务流程

最后更新于:2022-04-02 00:22:38

[16.3.1 用户注册流程](16.4.1 用户注册流程.md) [16.3.2 普通用户和管理员登陆流程](16.4.2 普通用户和管理员登陆流程.md) [16.3.3 发贴流程](16.4.3 发贴流程.md) [16.3.4 回复流程](16.4.4 回复流程.md) [16.3.5 版块管理流程](16.4.5 版块管理流程.md) [16.3.6 版主业务流程](16.4.6 版主业务流程.md) [16.3.7 金币奖励和消耗流程](16.4.7 金币奖励和消耗流程.md)
';