1.改进
在上一篇使用PHP编写留言板的结尾处,写了留言板的不足之处。经过一周的PHP学习,打算重新写一遍留言板,对之前的不足做出改进。
1.1删除功能
新的留言板添加了编辑选项,可以修改留言内容或删除留言。
1.2重复提交
新的留言板添加了session,而且在提交表单之后会自动跳转到留言板的主页,从而解决了重复提交的Bug。
1.3时间显示问题
在上一篇其实已经写出了解决方案,新的留言板会使用上次的方案来解决时间显示问题。
2.功能介绍
2.1删除留言
1 | <?php |
删除功能的实现,是通过在编辑页面点击链接时使用GET方式传入留言的ID,获得留言的ID后,通过PDO操作数据库删除留言。
2.2登陆
1 | <?php |
2.3退出
1 | <?php |
2.4发布留言
1 | <?php |
2.5注册
1 | <?php |
2.6编辑留言
1 |
|
编辑留言功能实现的方式和删除留言的一样的,都是通过在编辑页面使用GET方式将留言ID传入到编辑留言页面,再通过一个隐藏的表单将留言ID所使用POST方式传入到编辑页面功能中,然后再使用PDO操作数据库编辑留言。
2.7Session
1 | session_start(); |
2.7.1session_start()
在把用户信息存储在$_SESSION数组之前,必须先启动会话。
session_start()就是启动会话的函数。session_start()这个函数一般写在最开始的地方,在<html>标签之前即可。
2.7.2存储或取回session变量
存储或取回都需要使用到$_SESSION变量。
上面的代码中,将用户登录名(userName)存储到了$_SESSION中,在后面比对是也使用的是userName。
2.7.3简单的登陆判断
使用if判断$_SESSION[‘userName’]是否为空来判断用户是否已经登陆,如果$_SESSION[‘userName’]为空,则跳转到登陆页面。
2.7.4删除session数据
unset($_SESSION[‘userName’])和session_destory()都可以实现删除session数据的操作。在退出功能中写入,可以确保用户退出留言板。
3.数据库
MessageBoard数据库有2个表,user表存放用户的注册信息,messages存放用户发布的留言。
3.1user表结构
3.2messages表结构
4.显示页面
4.1编辑页面
1 | <!DOCTYPE html> |
使用GET方式通过<a>标签将留言ID发送到对应功能或页面。
4.2主页面(显示留言)
1 | <!DOCTYPE html> |
4.3登陆页面
1 | <!DOCTYPE html> |
4.4发布留言页面
1 | <!DOCTYPE html> |
4.5注册页面
1 | <!DOCTYPE html> |
4.6修改留言页面
1 | <!DOCTYPE html> |
5.PDO
PDO是 PHP Date Object (PHP数据对象)的简称,目前支持的数据库包括Firebird, FreeTDS,Interbase ,MySQL,MS SQL Server, ODBC, Oracle,Postgre SQL,SQLite 以及 Sybase等。有了PDO,用户就不必再使用 mysql_*函数,aco_函数或者 mssql_\函数,也不必再将他们封装到数据库操作类,只需要使用PDO接口中的方法就可以对不同的数据库进行操作,在选择不同数据库时,只需要修改PDO的 DNS(数据库名)就可以了。
5.1PDO构造函数连接数据库
PDO构造函数的形式:
1 | _construct(string $dsn[,string $username[,string $password[,array $driver_options]]]) |
$dsn:主机IP地址及数据库名称
1 | $dsn="mysql:host=$host;dbName=$dbName" |
$username:数据库用户名
$password:数据库密码
$driver_options:连接数据库的其他选项
通过PDO连接数据库
1 |
|
5.2使用PDO执行SQL语句
在PDO中,可以使用3中方式执行SQL语句,分别是exec()方法,query方法,以及预处理语句prepare()和execute()方法
5.2.1PDO::exec()方法
exec()方法形式如下:
1 | int PDO::exec(string $statement) |
PDO::exec()执行一条SQL语句,并返回受影响的行数。
$statement是要执行的SQL语句。
通过exec()方法执行SQL语句
1 |
|
5.2.2PDO::query()方法
query()方法形式如下:
1 | PDOStatement PDO::query(string $statement) |
PDO::query()可执行多条SQL语句,并以PDOStatement对象形式返回结果集。
通过PDO::query()执行SQL语句
1 |
|
5.2.3预处理语句:PDO::prepare()语句和execute()语句
PDO::prepare()方法形式如下:
1 | PDOStatement PDO::prepare(string $statement[,array $driver_options]) |
PDOStatement::execute方法形式如下:
1 | bool PDOStatement::execute([array $input_parameters]) |
PDO::prepare()方法为PDOStatement::execute()方法准备待执行的SQL语句。SQL 语句可以包含零个或多个参数占位标记,格式是命名(:name)或问号(?)的形式,当它执行时将用真实数据取代。 在同一个 SQL 语句里,命名形式和问号形式不能同时使用;只能选择其中一种参数形式。
PDOStatement::execute()方法执行一条预处理语句。
使用预处理语句执行SQL语句:
1 |
|
5.3PDOStatement::fetch
5.3.1PDOStatement::fetch
PDOStatement::fetch形式如下:
1 | mixed PDOStatement::fetch ([ int $fetch_style [, int $cursor_orientation = PDO::FETCH_ORI_NEXT [, int $cursor_offset = 0 ]]] ) |
5.3.1.1参数-$fetch_style
控制下一行如何返回给调用者。此值必须是 PDO::FETCH_* 系列常量中的一个,缺省为 PDO::ATTR_DEFAULT_FETCH_MODE的值 (默认为 PDO::FETCH_BOTH)。
参数 | 效果 |
---|---|
PDO::FETCH_ASSOC | 返回一个索引为结果集列名的数组 |
PDO::FETCH_BOTH(默认) | 返回一个索引为结果集列名和以0开始的列号的数组 |
PDO::FETCH_BOUND | 返回 TRUE ,并分配结果集中的列值给 PDOStatement::bindColumn() 方法绑定的 PHP 变量。 |
PDO::FETCH_CLASS | 返回一个请求类的新实例,映射结果集中的列名到类中对应的属性名。如果 fetch_style 包含 PDO::FETCH_CLASSTYPE(例如:PDO::FETCH_CLASS |
PDO::FETCH_INTO | 更新一个被请求类已存在的实例,映射结果集中的列到类中命名的属性 |
PDO::FETCH_LAZY | 结合使用 PDO::FETCH_BOTH 和 PDO::FETCH_OBJ,创建供用来访问的对象变量名 |
PDO::FETCH_NUM | 返回一个索引为以0开始的结果集列号的数组 |
PDO::FETCH_OBJ | 返回一个属性名对应结果集列名的匿名对象 |
5.3.1.2参数-$cursor_orientation
对于 一个 PDOStatement 对象表示的可滚动游标,该值决定了哪一行将被返回给调用者。此值必须是 PDO::FETCH_ORI_* 系列常量中的一个,默认为 PDO::FETCH_ORI_NEXT。要想让 PDOStatement 对象使用可滚动游标,必须在用 PDO::prepare() 预处理SQL语句时,设置 PDO::ATTR_CURSOR 属性为 PDO::CURSOR_SCROLL。
5.3.1.3参数-$offset
对于一个 cursor_orientation 参数设置为 PDO::FETCH_ORI_ABS 的PDOStatement 对象代表的可滚动游标,此值指定结果集中想要获取行的绝对行号。
对于一个 cursor_orientation 参数设置为 PDO::FETCH_ORI_REL 的PDOStatement 对象代表的可滚动游标,此值指定想要获取行相对于调用 PDOStatement::fetch() 前游标的位置
5.3.2PDOStatement::fetchAll
PDOStatement::fetchAll形式如下
1 | array PDOStatement::fetchAll ([ int $fetch_style [, mixed $fetch_argument [, array $ctor_args = array() ]]] ) |
5.3.2.1参数-$fetch_style
控制返回数组的内容如同 PDOStatement::fetch() 文档中记载的一样。默认为 PDO::ATTR_DEFAULT_FETCH_MODE 的值( 其缺省值为 PDO::FETCH_BOTH )
想要返回一个包含结果集中单独一列所有值的数组,需要指定 PDO::FETCH_COLUMN 。通过指定 column-index 参数获取想要的列。
想要获取结果集中单独一列的唯一值,需要将 PDO::FETCH_COLUMN 和 PDO::FETCH_UNIQUE 按位或。
想要返回一个根据指定列把值分组后的关联数组,需要将 PDO::FETCH_COLUMN 和 PDO::FETCH_GROUP 按位或。
5.3.2.2参数-$fetch_argument
参数 | 效果 |
---|---|
PDO::FETCH_COLUMN | 返回指定以0开始索引的列 |
PDO::FETCH_CLASS | 返回指定类的实例,映射每行的列到类中对应的属性名 |
PDO::FETCH_FUNC | 将每行的列作为参数传递给指定的函数,并返回调用函数后的结果 |
5.3.2.3参数-$ctor_args
当 fetch_style 参数为 PDO::FETCH_CLASS 时,自定义类的构造函数的参数。
5.3.3PDOStatement::fetchColumn
PDOStatement::fetchColumn形式如下:
1 | string PDOStatement::fetchColumn ([ int $column_number = 0 ] ) |
5.3.3.1参数-column_number
你想从行里取回的列的索引数字(以0开始的索引)。如果没有提供值,则 PDOStatement::fetchColumn() 获取第一列。
5.3.4PDOStatement::fetchObject
PDOStatement::fetchObject形式如下:
1 | mixed PDOStatement::fetchObject ([ string $class_name = "stdClass" [, array $ctor_args ]] ) |
5.3.4.1参数-class_name
创建类的名称。
5.3.4.2参数-ctor_args
此数组的元素被传递给构造函数。
6.缺陷
没有考虑防御手段。
7.参考
[1] php实现留言板功能
[2] PDO中执行SQL语句的三种方法
[4] T-SQL教程
[5] PHP Sessions
[6] PHP:PDO-Manual