11.4 Session会话技术
从浏览器用户第一次访问服务器开始,到断开与服务器的连接为止,形成一个Session会话生命周期。在此期间,服务器为每个浏览器用户分配唯一的Session ID标识当前用户,Session ID是一个加密的随机字符串,能保证其唯一性和随机性,Session信息保存在服务器端,确保了Session的安全。
11.4.1 Session工作原理
Session工作原理如图11-9所示。
浏览器向某WEB服务器中的某个页面(page1)第一次发出请求,page1页面接收到请求后产生一个独立的标记标识该请求(例如 btek48cklarn1m73eg2qkcsu12),同时产生与标记名称一一对应的Session文件保存在WEB服务器硬盘中。page1页面向第一次的响应头中添加一个Cookie响应头信息(该Cookie响应头信息格式如图11-9所示)。在page1页面的响应发送给浏览器前,page1页面操作该Session文件,例如可以向Session文件添加用户个人信息。page1页面的响应发送给浏览器时,Cookie响应头信息随着响应发送给浏览器。此时浏览器与WEB服务器之间完成了第一次请求与第一次响应。
浏览器收到Cookie响应头信息后,由于该Cookie没有设置Expire,浏览器将该Cookie视为会话Cookie,将Cookie信息以“键值对”的方式保存在浏览器进程使用的内存中。
当浏览器再次向该WEB服务器的其他页面(page2)发送第二次请求时,自动将浏览器中的Cookie信息放入到第二次请求头中(Cookie请求头信息格式如图11-9所示)。page2页面接收该Cookie信息中的Session标记“btek48cklarn1m73eg2qkcsu12”后,从该Session标记对应的Session文件中取出用户个人信息,从而实现同一WEB服务器内不同页面间的参数传递。
11.4.2 Session和Cookie的区别
Session文件用于存储每个浏览器用户个人信息,且所有Session文件存放于服务器,为了避免对服务器系统造成过大的负荷,Session 也存在过期时间的概念。Session 会因过期时间到期而自动失效,这是和Cookie的相同之处。Session和Cookie有以下几个区别。
(1)Cookie采用的是在浏览器端保持状态的方案,Session采用的是在服务器端保持状态的方案。Session的实现需要在浏览器端保存一个Session ID标记,Session机制可能需要借助Cookie保存该实现Session ID标记,但实际上还有其他选择。
(2)浏览器用户可以禁用浏览器的Cookie,却无法停止WEB服务器Session 的使用。
(3)在使用Session时,关闭浏览器只会使存储在浏览器端主机内存中的会话Cookie信息失效,不会使服务器端的 Session 信息失效。当浏览器用户下次登入网站时,服务器生成一个新的Session标记以及对应的Session文件以供使用。
(4)在使用Session时,第一次请求page1页面时,由于page1页面在服务器产生Session信息,因此page1页面可以直接对该Session信息进行访问。而Cookie信息保存在浏览器端,只有page1页面第一次响应后,才会产生Cookie信息,因此第一次请求page1页面时,page1页面不能访问到Cookie信息。
(5)Session可以存储复合数据类型的数据,例如数组或对象;而Cookie只能存储字符串数据。
11.4.3 PHP使用Session的步骤
PHP使用Session的步骤如下(如图11-10所示)。
(1)浏览器第一次请求访问 WEB 服务器中的 page1 页面时,page1 页面通过调用session_start()函数开启 Session,在开启 Session 的过程中,会产生一个独有的 Session 标记(Session ID)标识该浏览器的请求,并创建一个以Session ID命名的Session文件和Cookie响应头信息。此时Session文件大小为0KB,Cookie响应头信息则以Session name 作为“键”(默认值为PHPSESSID),以Session ID标记作为“值”。
(2)page1页面使用预定义变量$_SESSION实现用户个人信息在Session文件中的注册、读取、修改和释放,此时Session文件的大小也会随之发生变化。
(3)page1页面执行结束后,Cookie响应头信息随着page1页面的响应发送给浏览器。
(4)浏览器接收到该Cookie响应头信息后,若浏览器开启了Cookie,浏览器将Cookie“键值对”信息保存到浏览器进程使用的内存中。
(5)当浏览器第二次请求该WEB服务器的page2页面时,浏览器将其内存中Cookie信息封装到第二次请求中,向page2页面发出请求。
(6)page2 页面重新调用 session_start()函数开启 Session,在开启 Session 的过程中,由于Cookie 请求头中存在Session ID,page2页面不再产生新的Session ID,从而判断是同一个浏览器用户发送的第二次请求。
(7)page2 页面通过调用 session_start()函数从 Cookie 请求头中获取 Session ID,继而找到Session ID对应的Session文件,然后将Session文件中的数据解析到预定义变量$_SESSION中, page2页面通过$_SESSION可以访问到page1页面向Session文件写入的信息,从而实现不同页面间的参数传递。
(8)浏览器关闭后,会话Cookie从浏览器端内存中删除,与浏览器对应的Session文件依旧存在,直到Session的过期时间到期。
若浏览器关闭了Cookie,解决办法是将Session name和Session ID附在URL后作为查询字符串在浏览器和WEB服务器之间进行传递,服务器与浏览器通过Session ID来保持彼此间的联系。
一般而言 PHP 对于 Session 的过期时间并无定义,但 PHP 开发人员可以通过修改php.ini 配置文件中的 session.cookie_lifetime 选项,设置 Session 的过期时间。session.cookie_lifetime 以秒数指定了发送到浏览器的 Cookie 的生命周期,默认值为 0,表示“关闭浏览器时Session失效”。
11.4.4 Session在php.ini文件中的配置
php.ini配置文件中有一组如下Session的配置选项,实现Session的设置。
(1)session.save_handler = files:设置服务器保存用户个人信息时的保存方式,默认值为“files”,表示用文件存储 Session 信息。如果想要使用数据库存储 Session 信息,可将session.save_handler选项设为“user”。
(2)session.save_path = "c:/wamp/tmp":在save_handler 设为files时,用于设置Session文件的保存路径。
(3)session.use_cookies = 1:默认的值是1,代表SessionID使用Cookie传递(推荐使用);为0时使用查询字符串传递。
(4)session.name = PHPSESSID:Session ID 的名称,默认值为“PHPSESSID”。不管使用Cookie 传递Session ID还是使用查询字符串传递Session ID,都需要指定Session ID的名称。
(5)session.auto_start = 0 :在浏览器请求服务器页面时,是否自动开启Session,默认值为0,表示不自动开启Session(推荐使用)。
(6)session.cookie_lifetime = 0:设置Session ID在Cookie中的过期时间,默认值为0,表示浏览器一旦关闭Session ID立即失效(推荐使用)。
(7)session.cookie_path = / :使用Cookie传递Session ID时Cookie的有效路径,默认为“/”。
(8)session.cookie_domain =:使用Cookie传递Session ID时Cookie的有效域名,默认为空。
(9)session.gc_maxlifetime = 1440:设置Session文件在服务器端的储存时间,如果超过这个时间,那么 Session 文件会自动删除。默认为 1 440s(24min),表示 1 440s 无操作就会自动销毁该Session文件。
11.4.5 开启Session
Session的使用不同于Cookie,必须在PHP中调用session_start()函数启动Session后才能使用Session。session_start()函数语法格式非常简单:bool session_start ( void )。该函数没有参数,且返回值永为TRUE。session_start()函数的主要功能如下。
(1)加载php.ini配置文件中有关Session的配置信息(例如Session生存期、Session保存路径等信息)至WEB服务器内存。
(2)创建Session ID或使用已有的Session ID(例如btek48cklarn1m73eg2qkcsu12)。原则是:若请求头中存在形如“Set-Cookie: PHPSESSID= btek48cklarn1m73eg2qkcsu12;”的Cookie信息,则直接使用该 Session;若请求头中不存在形如“Set-Cookie: PHPSESSID= btek48cklarn1m73 eg2qkcsu12;”的Cookie信息,创建一个新的Session ID标识该请求。
(3)在 WEB 服务器创建 Session 文件或解析已有的 Session 文件。原则是:创建 Session ID时,则创建Session文件;使用已有的Session ID时,则将Session文件中的内容解析到预定义变量$_SESSION中。
(4)产生Cookie响应头信息,Cookie响应头信息会随着响应发送给浏览器,该Cookie响应头信息形如“Set-Cookie: PHPSESSID= btek48cklarn1m73eg2qkcsu12;”。
说明:Session文件用于保存浏览器用户的个人信息,以便实现PHP页面间参数传递。Session文件的文件名默认格式为 sess_和 Session ID 的组合,例如某 Session 文件名为:sess_btek48cklarn1m73eg2qkcsu12。该文件默认存储在“C:/wamp/tmp”目录下,刚创建时文件大小为0KB,表示Session中没有保存任何有关用户信息。
PHP程序开启Session时,程序会产生Cookie响应头信息,因此在使用session_start()函数开启Session 之前,浏览器不能有任何输出。
如果不想让每个页面都使用session_start()函数来开启Session,可以在php.ini 配置文件中修改session.auto_start选项,修改为session.auto_start=1。但启用该选项也有一些限制,例如不能将对象放入会话中,也不可以进行Session 持久化的工作。
11.4.6 Session ID、Session name和SID
Session ID用于标识Session,为了保证Session的安全性与唯一性,Session ID是一个经过加密的随机字符串。该随机字符串由 session_start()函数生成,可以使用 session_id()函数取得当前Session ID的值。
session_id()函数语法格式:string session_id ( [string id] )
session_id()函数功能:该函数既可以设置当前Session ID 的值(此时必须在session_start()函数调用前使用),又可以取得当前Session ID的值(此时必须在session_start()函数调用后使用)。该函数返回一个Session ID标记。
PHP为每个Session提供一个Session名,可以使用session_name()函数取得当前Session的name值。
session_name()函数语法格式:string session_name( [string name] )
session_name()函数功能:该函数既可以设置当前Session name的值(此时必须在session_start()函数调用前使用),也可以取得当前 Session name 的值(此时必须在 session_start()函数调用后使用)。该函数返回一个字符串。
PHP还定义了一个常量SID,SID常量为字符串类型数据,格式为:Session name=Session ID。在浏览器请求某PHP页面(该PHP程序开启了Session)时,如果请求中不包含形如“Set-Cookie: PHPSESSID= btek48cklarn1m73eg2qkcsu12;”的Cookie请求头信息,将产生SID常量;否则SID的值为空字符串。
当用户将浏览器的Cookie禁用时,可以使用Session ID、Session name或者SID跟踪该浏览器用户,从而实现页面间的参数传递,实现会话控制功能。
程序session.php演示了session_id()函数、session_name()函数和SID的用法(为保证实验成功,这里使用了Firefox浏览器),该程序的代码如下。
<?php
session_start();
echo session_id();
echo "<br/>";
echo session_name();
echo "<br/>";
echo SID; //产生的SID格式为:Session name=Session ID
?>
<br/>
<a href="session.php">刷新</a>
实验1开启Firefox浏览器Cookie的设置
使用Firefox浏览器访问该程序时,开启Firefox浏览器Cookie以后,session.php页面运行结果如图11-11所示。单击刷新超链接后,浏览器再次向session.php页面发送请求,session.php程序运行结果如图11-12所示。
从结果可以看出,第一次访问 session.php 页面时,由于请求头中没有包含形如PHPSESSID=Session ID的Cookie信息,session.php页面后将产生SID字符串。当浏览器用户单击刷新超链接第二次请求 session.php 页面时,此时请求头中包含了形如 PHPSESSID=Session ID的Cookie信息,第二次请求session.php页面后SID的值为空字符串。并且第一次访问session.php页面时产生的Session ID和单击刷新超链接后重新访问session.php页面的Session ID相同,这样就实现了使用Session跟踪浏览器用户的功能。
实验2禁用Firefox浏览器Cookie的设置
禁用 Firefox浏览器的 Cookie,并重启浏览器后,浏览器第一次向 session.php程序发出请求访问session.php页面,此时session.php页面运行结果如图11-13所示。单击刷新超链接后,浏览器再次向session.php页面发送请求,但由于浏览器的Cookie被禁用,请求头中没有包含形如PHPSESSID=Session ID 的Cookie 信息,因此session.php 程序将产生新的Session ID 标识该请求,session.php程序运行结果如图11-14所示(每次刷新session.php页面时,都会产生不同的Session ID)。
实验2说明,当禁用了Firefox浏览器的Cookie后,刷新页面时产生的新的请求“来自于不同的用户”,这样就无法做到用户的跟踪。解决方法是:在 URL 后附加 SID (或者session_name()=session_id())查询字符串实现PHP页面间Session ID的传递,或者使用表单隐藏域“<input type="hidden" name="<?php echo session_name();?>" value=" echo session_id();">”实现PHP页面间Session ID的传递,从而实现用户的跟踪。
实验3禁用Firefox浏览器Cookie的设置
将sesson.php的程序修改为如下代码(粗体字部分为代码的改动部分,其他代码不变)。
<?php
if(isset($_GET['PHPSESSID'])){
session_id($_GET['PHPSESSID']);
}
session_start();
……
echo SID; //产生的SID格式为:Session name=Session ID
?>
<br/>
<a href="session.php?<?php echo SID?>">刷新</a>
此时即便用户禁用了 Firefox 浏览器的 Cookie,由于 SID 作为查询字符串通过超链接附在URL后,单击刷新超链接后同样可以实现用户的跟踪。重启浏览器后,浏览器第一次向session.php程序发出请求访问session.php页面,此时session.php页面运行结果如图11-15所示。单击刷新超链接后,浏览器将向session.php页面传递SID查询字符串,将Session ID传递到session.php页面, session.php页面获取Session ID,并调用session_id()函数设置Session ID,从而实现用户的跟踪, session.php页面运行结果如图11-16所示。
除了可以将SID作为查询字符串附在URL后跟踪用户外,也可以使用表单隐藏域传递SID,其原理和前者相同,这里不再赘述。Cookie可以被人为地禁止,因此手工传递SID是跟踪浏览器用户的万能方法。
11.4.7 预定义变量$_SESSION
PHP提供了预定义变量$_SESSION解析和修改Session文件,$_SESSION和$_COOKIE一样也是一个全局数组。$_SESSION的功能如下。
(1)可以使用$_SESSION 数组的赋值语句添加数组元素或修改数组元素,服务器将这些元素以“键名|值类型:长度:值”的格式序列化到Session对应的Session文件中。
在使用$_SESSION数组操作Session文件前必须先用session_start()函数启动Session。
有些类型的数据不能被序列化,因此也就不能保存在会话中,例如resource 变量或者有循环引用的对象(即某对象将一个指向自己的引用传递给另一个对象)。
(2)可以使用$_SESSION数组读取Session文件中的信息。
(3)可以使用unset()函数释放内存中$_SESSION数组的某些元素,此时Sessions文件中的对应信息也将被删除,但该函数无法删除Session文件。
若想清除$_SESSION 数组中的所有元素,可以使用语句“$_SESSION=array();”实现。不能使用语句“unset($_SESSION)”删除$_SESSION 数组的定义,否则不能通过$_SESSION维护Session文件。
11.4.8 删除和销毁Session
PHP提供了session_unset()函数和session_destroy()函数用于销毁Session。
session_unset()函数语法格式:void session_unset ( void )
session_unset()函数功能:删除当前内存中$_SESSION数组中的所有元素,并删除Session文件中的用户信息,并不删除Session文件以及不释放对应的Session ID。session_unset()函数等效于“$_SESSION=array();”。
session_destroy()函数语法格式:bool session_destroy ( void )
session_destroy()函数功能:销毁Session 文件,并将Session ID 置为0。 销毁成功后函数返回TRUE,否则返回FALSE。
使用 session_unset()函数可以删除服务器内存中的$_SESSION 数组中的所有元素及Session文件中的用户信息;使用session_destroy()函数可以删除服务器硬盘中的Session文件并释放对应的 Session ID。但若要彻底删除 Session的所有资源,还需清除浏览器内存中的Cookie信息,可以调用setcookie()函数将会话Cookie设置为过期即可。
11.4.9 Session的综合应用
下面的6个PHP程序演示了如何使用PHP实现Session的管理,这些程序操作同一个Session文件,完成Session文件的创建、向Session文件中写入“键值对”信息、修改Session文件中的某个“键值对”信息、删除Session文件的某个“键值对”信息、删除Session文件中所有的“键值对”信息以及删除Session文件等操作。
add_session.php程序负责创建Session文件,然后向Session文件中写入账户信息(用户名为“admin”,密码为“admin”经md5加密后的数据),最后提供一个读取Session文件中账户信息的超链接。add_session.php程序代码如下。
<?php
session_start();
$_SESSION["user_name"] = "admin";
$_SESSION["password"] = md5("admin");
echo "添加Sessions信息";
?>
<br/>
<a href="read_session.php">读取Session信息</a>
read_session.php程序负责读取和显示Session文件中的账户信息,然后提供4个超链接,分别为:修改Session文件中的密码信息、删除Session文件中的密码信息、删除Session文件中的所有信息和销毁Session所有资源。read_session.php程序代码如下。
<?php
session_start();
echo "读取Sessions信息";
echo "<br/>";
echo "用户名:";
if(isset($_SESSION["user_name"])){
echo $_SESSION["user_name"];
}
echo "<br/>";
echo "密 码 :";
if(isset($_SESSION["password"])){
echo $_SESSION["password"];
}
echo "<br/>";
?>
<br/>
<a href="update_session.php">修改Session文件中的密码信息</a>
<br/>
<a href="delete_session.php">删除Session文件中的密码信息</a>
<br/>
<a href="delete_all_session.php">删除Session文件中的所有信息</a>
<br/>
<a href="destroy_session.php">销毁Session所有资源</a>
update_session.php程序负责修改Session文件中密码信息,然后提供“重新读取Session文件账户信息”超链接。update_session.php程序代码如下。
<?php
session_start();
$_SESSION["password"] = md5("654321");
echo "修改Sessions中密码信息";
?>
<br/>
<a href="read_session.php">重新读取Session文件账户信息</a>
delete_session.php程序负责删除Session文件中密码信息,然后提供“重新读取Session文件账户信息”超链接。delete_session.php程序代码如下。
<?php
session_start();
unset($_SESSION["password"]);
echo "删除Sessions中密码信息";
?>
<br/>
<a href="read_session.php">重新读取Session文件账户信息</a>
程序delete_all_session.php负责删除Session文件所有账户信息(Session文件无法通过该程序删除),然后提供“重新读取Session文件账户信息”超链接。delete_all_session.php程序代码如下。
<?php
session_start();
$_SESSION = array();
echo "删除Session所有信息";
?>
<br/>
<a href="read_session.php">读取Session信息</a>
程序 destroy_session.php 负责删除 Session 文件所有账户信息,并将 Session 文件删除。destroy_session.php程序代码如下。
<?php
session_start();
session_unset();
if(isset($_COOKIE[session_name()])){
setcookie(session_name(),session_id(), time()-10);
}
session_destroy();
echo "销毁Session所有资源";
?>
11.4.10 新闻发布系统用户管理功能的实现(二)
使用Session可以实现新闻发布系统的管理员用户登录和注销功能。
1.登录功能的实现
普通用户在新闻发布系统的登录页面中输入正确的用户名和密码信息,单击登录按钮后,将用户信息(例如user_id和name)放入到Session文件中,从而实现用户登录功能。新闻发布系统用户登录功能的实现步骤如下。
(1)修改login_process.php程序,向login_process.php程序中添加新的功能:当浏览器用户输入正确的用户名和密码登录新闻发布系统时,login_process.php 程序负责将用户的 user_id 和name信息放入到Session中。修改后的login_process.php代码如下(粗体字部分为代码的改动部分,其他代码不变)。
<?php
……
if(mysql_num_rows($result_set)>0){
if(isset($_POST["expire"])){
$expire = time()+intval($_POST["expire"]);
setcookie("name",$name,$expire);
setcookie("password",$first_password,$expire);
}
session_start();
$admin = mysql_fetch_array($result_set);
$_SESSION['user_id'] = $admin['user_id'];
$_SESSION['name'] = $admin['name'];
header("Location:login.php?login_message=password_right");
}else{
header("Location:login.php?login_message=password_error");
}
close_connection();
?>
(2)编写自定义函数is_login()函数,is_login()函数的语法格式为:bool is_login(void)。该函数实现的功能是判断管理员用户是否登录。在“C:\wamp\www\news\functions”目录下创建is_login.php程序,代码如下。
<?php
function is_login(){
if(isset($_SESSION["user_id"])){
return TRUE;
}else{
return FALSE;
}
}
?>
is_login()函数使用说明:在调用is_login()函数前,需调用session_start()函数开启Session。
(3)修改login.php程序,向login.php程序添加新的功能:判断当前用户是否是管理员用户,若是则显示欢迎信息,并生成“注销”超链接,然后使用return流程控制语句退出login.php程序的运行;否则显示登录表单以便用户登录。修改后的login.php代码如下(粗体字部分为代码的改动部分,其他代码不变)。
<?php
session_start();
include_once("functions/is_login.php");
if(isset($_GET["login_message"])){
if($_GET["login_message"]=="password_error"){
echo "密码错误,重新登录!<br/>";
}else if($_GET["login_message"]=="password_right"){
echo "登录成功!<br/>";
}
}
if(is_login()){
echo "欢迎".$_SESSION['name']."访问系统!<br/>";
echo "<a href='logout.php'>注销</a>";
return;
}
$name = "";
……
</form>
login.php程序说明:为了方便页面间的相互引用,login.php程序使用了return语句而没有使用exit语句退出程序的运行。这是因为exit会结束所有脚本程序(包括引用者脚本程序)的运行,而使用return只会结束当前脚本程序的运行,不会结束引用者脚本程序的运行。
2.注销功能的实现
管理员用户登录成功后,新闻发布系统应提供“注销”功能方便管理员退出系统。在“C:\wamp\www\news”目录下创建logout.php程序,该程序负责删除Session的所有资源,注销成功后将页面重定向到登录页面login.php。logout.php程序代码如下。
<?php
session_start();
session_unset();
if(isset($_COOKIE[session_name()])){
setcookie(session_name(),session_id(), time()-10);
}
session_destroy();
header("Location:login.php");
?>
至此,新闻发布系统用户管理中普通用户登录与管理员用户注销的功能开发完毕。
11.4.11 新闻发布系统权限控制的实现
对于新闻发布系统而言,只有管理员用户能够发布新闻、编辑新闻和删除新闻信息,只有管理员用户才可以对评论进行审核和删除,游客不具有这些后台管理操作的权限。识别管理员和游客的最简单方法是使用 Session 对用户进行全程跟踪,从而实现新闻发布系统的权限控制,具体步骤如下。
(1)修改“C:\wamp\www\news”目录下的news_add.php程序,向news_add.php程序添加新的功能:只有登录成功后的管理员用户才可以访问该程序的form表单。修改后的news_save.php代码如下(粗体字部分为代码的改动部分,其他代码不变)。
<?php
include_once("functions/is_login.php");
session_start();
if(!is_login()){
echo "请您登录系统后,再访问该页面!";
return;
}
?>
<form action="news_save.php" method="post" enctype="multipart/form-data">
……
</form>
使用同样的方法修改 news_delete.php、news_edit.php、news_update.php、review_list.php、review_delete.php和review_verify.php程序的代码,将页面内容“保护”起来,这样只有登录成功的管理员用户才有权访问这些页面,具体实现过程这里不再赘述。
(2)修改“C:\wamp\www\news”目录下的news_save.php程序,向news_save.php程序添加另一个新的功能:实现登录用户的跟踪。修改后的 news_save.php 代码如下(粗体字部分为代码的改动部分,其他代码不变)。
<?php
include_once("functions/is_login.php");
session_start();
if(!is_login()){
echo "请您登录系统后,再访问该页面!";
return;
}
include_once("functions/file_system.php");
if(empty($_POST)){
$message = "上传的文件超过了php.ini中post_max_size选项限制的值";
}else{
$user_id = $_SESSION["user_id"];
$category_id = $_POST["category_id"];
……
close_connection();
}
}
header("Location:news_list.php?message=$message");
?>
(3)修改“C:\wamp\www\news\news”目录下的news_list.php程序,向news_list.php程序添加新的功能:只有登录成功后的管理员用户可以看到该页面中的“编辑”和“删除”超链接,普通用户无法看到该页面中的“编辑”和“删除”超链接,避免普通用户的误操作。修改后的news_list.php代码如下(粗体字部分为代码的改动部分,其他代码不变)。
<?php
include_once("functions/database.php");
include_once("functions/page.php");
include_once("functions/is_login.php");
session_start();
//显示文件上传的状态信息
if(isset($_GET["message"])){
echo $_GET["message"]."<br/>";
}
……
<tr>
<td>
<a href="news_detail.php?news_id=<?php echo $row['news_id']?>"><?php echo$row['title']?></a>
</td>
<?php
if(is_login()){
?>
<td>
<a href="news_edit.php?news_id=<?php echo $row['news_id']?>">编辑</a>
</td>
<td>
<a href="news_delete.php?news_id=<?php echo $row['news_id']?>">删除</a>
</td>
<?php
}
?>
</tr>
……
至此,新闻发布系统中的权限控制功能开发完毕。
11.4.12 Session数组
Session 可以存储复合数据类型的数据(例如数组或对象),此时数组或对象数据将被序列化到Session文件中,例如可以将会员选择的所有商品(products)放入数组,然后将该数组序列化到Session文件中实现网上购物功能。下面3个程序shopping.php、add.php和cancel.php使用Session数组模拟了网上购物系统中购物车的功能,这3个程序的具体分工以及编写步骤如下。
(1)在“C:\wamp\www\11”目录下创建“cart”目录。
(2)在“cart”目录下创建shopping.php程序,该程序实现的功能依次是:首先罗列一些商品信息,并为每个商品提供一个“添加到购物车”的超链接,然后将购物车中的所有商品信息罗列出来,并为购物车中的每个商品提供一个“取消购买”的超链接。shopping.php程序代码如下。
<?php
session_start();
?>
商品1 <a href="add.php?product_id=1">添加到购物车</a><br/>
商品2 <a href="add.php?product_id=2">添加到购物车</a><br/>
商品3 <a href="add.php?product_id=3">添加到购物车</a><br/>
商品4 <a href="add.php?product_id=4">添加到购物车</a><br/>
商品5 <a href="add.php?product_id=5">添加到购物车</a><br/>
商品6 <a href="add.php?product_id=6">添加到购物车</a><br/>
<hr>
<?php
if(empty($_SESSION["products"])){
echo "您暂时没有购买商品。<br/>";
}else{
echo "您所购买的商品有:<br/>";
$products = $_SESSION["products"];
foreach($products as $key=>$value){
echo "商品$value <a href='cancel.php?product_id=$key'>取消购买</a><br/>";
}
}
?>
(3)在“cart”目录下创建add.php程序,该程序负责将特定的商品ID添加到购物车中,然后将页面重定向到shopping.php页面。add.php程序代码如下。
<?php
session_start();
$product_id = $_GET["product_id"];
$products = $_SESSION["products"];
$products[$product_id] = $product_id;
$_SESSION["products"] = $products;
header("Location:shopping.php");
?>
(4)在“cart”目录下创建cancel.php程序,cancel.php程序负责将特定的商品ID从购物车中删除,然后将页面重定向到shopping.php页面。cancel.php程序代码如下。
<?php
session_start();
$product_id = $_GET["product_id"];
unset($_SESSION["products"][$product_id]);
header("Location:shopping.php");
?>
该购物系统运行结果如图 11-17 所示,当前状态下,购物车对应的 Session 文件中的内容如图11-18所示。
共有条评论 网友评论