经典PHP留言本教程
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
教程连载1:PhpChina留言本实例
在第一期中,我们来一步一步实现一个最基本的留言本。
留言信息包括留言者,留言内容,留言时间,留言者IP。
(本文假设你已对HTML以及PHP语法比较熟练了)
第一步:设计数据库
新建一个数据库,打开phpMyAdmin,新建一个数据库gb,下面整理选择utf8_general_ci,然后在数据库中建一个表message,字段数为5:
utf8_general_ci。
每个字段的含义:
id-- 留言的编号,类型为整数型,长度是10,属性选择为unsigned是表明这个字段是无符号字段,不会有负数,所以可以存取的范围会增加一倍(因为如果原来的范围是-9 到10,那么设置为unsigned后范围则变为0到19),额外设置为auto_increment,表明这个字段是自动增加的,我们不用管插入数据时它是啥值,它会自动在最大的id的基础上自动加1,其他设置为主键。
username -- 留言者的名字,类型为字符型(关于char与varchar的区别请查看MYSQL手册),长度为100(正常人用户名不可能超过100吧,其实应该尽量减少长度,提高性能,节约空间)
content-- 即留言内容,类型为text(text和blob的唯一的区别在于text不区分大小写,而blob对字符的大小写),text类型可以存足够多的数据,足够存好几篇文章了,此类型不能设置长度,否则报错。
time -- 即发布留言的时间,类型为int,长度为10,保存的数据格式是UNIX时间戳(即用PHP函数time()得到的10位数字),而不存xxxx-xx-xx这样的格式,为何这样后面或解释。
ip -- 即留言者的IP,格式为xxx.xxx.xxx.xxx,总共15个字符,所以长度设置为15。
第二步:设计界面
在这我们直接偷蓝色理想的BXNA的界面( )
HTML和CSS的东西就不详细讲了,不然写10期也写不完这个留言本了 (在code文件
夹中有一个html文件,是单独分离出来的)
第三步:开始写程序咯
先要想好程序的整体构架,代码执行的流程等。
先说一下我们做的这个程序的整体运行流程:
程序是根据不同的URL参数(参数m和参数a)来调用不同的模块文件里的不同函数。
比如URL是index.php?m=user&a=info,则程序会先包含mod_user.php,并调用里面的函数user_info();,这个函数会返回一段HTML(不会直接输出,因为我们要用到smarty,最后一次性输出)或跳到别的页面。
所有的请求都是从index.php这个入口开始,mod文件不能被直接调用。
下面开始写程序入口部分:
首先建立一些引用的文件,放在includes文件夹下,比如一些常量config.inc.php,所有函数function.inc.php,后缀为PHP,这样通过浏览器直接访问这些文件将看到空白(没有输出)。
在config.inc.php中定义5个常量:
function.inc.php用来存放自定义函数。
在这一期中总共有3个自定义函数。
具体代码请查看文件,有详细注释。
print_mysql_error显示数据库错误信息,并终止脚本
get_client_ip取得用户IP
show_result_page显示结果页面,返回HTML
把smarty文件夹全拷过去。
(在后面会讲到简单用法)
然后建立首页index.php文件,具体代码请看附件中的对应文件。
其中比较重要的一些地方。
参数调用对应的功能模块。
在这一节中,我们只包含两个模块,即main和add,用来显示留言和添加留言。
根据不同的$_GET['m'],调用不同的mod文件。
然后根据不同的$_GET['a'],调用不同的函数。
比如$_GET['m'] == 'main',$_GET['a'] == 'up',则包含文件mods/mod_main.php,并
调用这个文件里的main_up()函数,来执行相应功能,比如显示留言。
默认调用main_page()函数。
后面有个使用smarty来实现HTML和PHP的分离,这样有利于美工和程序员协同工作。
如果你没有用过smarty或其他模板类也不用担心,我们会在后面介绍基本的用法。
但如果你想学好它,建议去它的官方站看看,并下载一份手册。
( )
由于针对初学者,在这我们就不使用MYSQL的类了,而直接使用PHP中自带的函数。
如果你现在直接访问index.php,他会提示mod_main.php文件不存在。
(因为默认是调用这个文件)
下面开始写模块部分
建立一个文件夹名为mods,用来存放所有模块文件。
建立我们需要的mod_main.php文件。
具体代码:
mod_main.php的主要流程:
if(!defined('IN')) die('Access denied');
这个用来确认该文件是否是被index.php文件包含(因为index.php包含了config.inc.php,而config.inc.php里定义了常量IN),如果IN常量没被定义,证明不是被index.php包含的,则结束脚本,并输出Access denied。
这是一个常用的防止一个文件被直接调用的方法。
先执行查询SELECT * FROM `message` ORDER BY `id` DESC
意思即查找message表中所有数据的所有字段,并按id字段倒序排列。
然后判断mysql_errno()是否为0,不为0则证明有错误,则用print_mysql_error()函数输出错误信息,并结束整个代码。
如果没有错误,则用while循环取得信息(一条留言循环一次)。
在循环中,先定义一个空数组$message_array = array();,然后每循环一次,往这个数组中插入另一个数组,组成一个二维数组。
存的都是留言信息。
循环完后$smarty->assign('message' , $message_array);即把$message_array变量赋予smarty中的message,用来做模板里的替换(即把模板里的$message部分替换为$message_array变量的值)。
最后return $smarty->fetch('message.tpl');即取得message.tpl模板的信息,替换模板变量后并返回。
打开template/bxna/message.tpl文件可以发现
这样一段代码,它的意思即循环输出,$message不是一个数组么,即循环输出这个数组。
其中[##$message[k].username##]这个意思是指这里要替换的内容是$message变量中的username,即用户名。
其它几个变量也一个道理。
循环的具体用法请参考smarty手册。
最后fetch(即取回嘛)整个HTML(已经把所有模板变量替换完成),返回给index.php 里的$main_body。
到这不知道大家是否了解smarty的工作流程了呢?
1.初始化smarty
2.用$smarty->assign设置要替换的变量,第一个参数是模板要被替换的部分。
3.用$smarty->fetch取回替换完后的模板(HTML),或用display直接输出。
在模板中smarty有几个基本语法,其实和php中差不多(边界符可以在初化时定义):1.[##if $var##]show something[##else##]show other thing[##/if##]
2.上面提到的循环结构section (你也可以用foreach,请查看smarty手册)
3.[##$var##] 直接输出变量
大部分时候就用到这几种结构就行了☺,还有一些比较高级的,比如可以在模板里截取字符串,格式化时间等等,都可以在手册中查看,都有比较详细的例子。
然后在index.php里$smarty->assign('main_body' , $main_body);替换模板变量并输出$smarty->display('index.tpl');
Smarty中display和fetch的唯一区别就是display等于echo fetch,即fetch完后再输出。
现在用phpMyAdmin往数据库里手工插入几条数据,然后刷新首页,即可看到效果了☺
这时你可以点击导航上面的Add链接,你会发现URL变了,但还是显示首页,为什么呢?看看URL可以发先此时参数m为add,a为空,所以程序会试图包含mod_add.php文件,但现在此文件还不存在(我们还没做到这步哈),所以程序会转为包含mod_main.php文件,并调用其中的main_page()函数,即和首页调用的同一个函数,显示同样的东西。
现在我们来做一个添加留言的模块add:
在mods文件夹下建立模块文件mod_add.php。
具体代码:
此函数的代码相当简单,就两行:
global $smarty;
return $smarty->fetch('add_form.tpl');
相信大家都能看懂了,其实就是直接取add_form.tpl文件,不经过任何模板变量替换直接返回给index.php里的$main_body,然后输出。
(一个表单,也没要替换的变量的)
显示出表单,我们得想办法往数据库里插入用户提交的留言信息了:
增加一个函数add_doadd(),用来处理用户的提交信息。
具体代码:
排版比较乱,具体请查看文件里的代码。
流程是先获得提交的信息,取得当前UNIX时间戳(10位数字),以及用户IP,然后插入数据库,并判断插入操作是否成功,真则返回成功信息,假则返回错误信息,并让用户返回上一页。
这时提交功能已经做成功了,你可以提交一些信息,并刷新首页,就可以看见刚提交的留言了。
可能你会发现提交空用户名和空留言也能提交成功。
这是因为我们没有判断用户的输入。
在$time = time(); 的上一行加入下列代码:
这样就行了,即判断是否为空,空则返回失败,并终止脚本。
在这解释以下为什么时间要用UNIX时间戳这样的10位数字,而不用我们熟悉的xxxx-xx-xx xx:xx:xx 这样的格式。
用时间戳的好处在于容易比较时间的大小(时间越靠后当然时间戳就越大),容易算出两饿时间之间间隔了多少秒,并可以转换为分,小时,天等。
比较灵活。
关于UNIX时间戳以及格式转换的详细信息可以查看php手册的time,date 和mktime等函数。
你是否发现此时提交的留言就算自己输入了换行,但显示时却不换行,而只显示一个空格呢?那是因为我们提交的换行是\n,这个只有在HTML源代码里才显示出换行,而浏览器中显示的换行应该是<br />,所以我们要进行以下替换,把留言内容中的\n替换为<br />。
为此,我们增加一个ubb.inc.php文件,放在includes文件夹下,它就一个函数ubb,并包含1个替换,具体代码请查看对应文件。
然后我们打开mod/mod_main.php,用此函数过滤一下留言内容$content:
找到
在他上面一行加入:
找到
把它替换为
即用ubb 函数过滤一下数据库种取出来的留言内容content
OK,你再提交留言然后回首页刷新一下就可以看见效果了☺
这就是第一节的内容了。
我们很容易发现这个留言本存在很多的BUG,比如提交的js代码会直接执行,不能分页,没有现在很普遍的UBB功能等等。
在下一期中我们会一步一步把它完善滴☺。