现在的位置: 首页 > 综合 > 正文

[PHP]会话小结

2015年03月13日 ⁄ 综合 ⁄ 共 3372字 ⁄ 字号 评论关闭


会话控制是一种跟踪用户的通信方式,使用会话控制主要基于以下几点:由于http协议的无状态性,使得不能通过协议来建立两次请求之间的关联;对于通常的页面之间的数据传递方式get和post而言,主要处理参数的传递、资料的输入两个页面间简单的数据传递,对于一个用户的在网站上的多个页面,多种不同的数据,可能还有权限的不同而导致页面的不同、操作方式的不同等等,使用get和post非常繁琐。

      1.cookie方式

      为了对用户进行跟踪,就必须对用户进行标记,cookie的思想就是,当用户访问网站的第一个页面时,通过设置用户的信息标识,web服务器将其以文本文件的形式存放到用户的电脑上面,这些文件就是所谓的cookie,以键值对的方式存储,当用户再访问第二个该网站的页面时,将通过http头信息,将携带cookie文件中的信息一起访问服务器,并重新对刚才的用户信息进行验证,这样避免了每次访问都输入用户信息,可以确定多个页面之间的访问是不是同一用户了。

      将信息设置到cookie的函数:setcookie($key, $value, $expire, $path, $domain, $secure)。

      参数依次是:键、值、过期时间(UNIX时间戳,默认为0表示关闭浏览器则cookie消失)、存取cookie的路径,设定后服务器上该路径下的脚本可存取cookie(默认为根目录)、存取cookie的域名,只有该域名(比如www.example.com)下的网站网页可存取cookie、是否是https安全连接才启用cookie。

      比如通过post提交表单后记录一些信息

<?php
    if(isset($_POST)){
        $time = time();
        setcookie('user', $_POST['user'], $time+3600);  // 时间参数需要比当前时间点大,以表示cookie信息的有效时间
        setcookie('data', array(1,2,3), $time+1200);  // 可以存放各种数据 
    }

       保存cookie成功后,可直接到$_COOKIE超全局数组中以键名取得该值,非常方便,如echo $_COOKIE['user'],基本的数据类型都支持

       cookie的删除仍是通过setcookie进行,最好写成将时间提前的形式,或者直接写一个键名,比如在用户点击退出时进行该项操作

    setcookie('user', '', time()-200);  // 时间提前,相对当前时间
    setcookie('user');  // 简写,只写键名

      2.session方式

      session与cookie相似,只是原来将信息存在用户端的,现在改为存到服务端,但在用户端产生一个标识id,这个id默认是保存到用户本地的cookie中,所以session又和cookie扯上了关系。这样用户第一次访问时将信息存到web服务器,并随机分配给用户一个固定长度的字符串(session id),以后用户再访问其他页面,就带着这个id去服务端里找对应用户数据信息,于是就可以跟踪用户了,使用cookie的session称为基于cookie的session。

      但是用户可以将浏览器设为禁用cookie(虽一般不会这么做),有的网站在检测到禁用cookie后会强制让用户去开启,但却是存在这么一种情况,如此一来通过基于cookie的方式行不通了,这时就可以通过在URL后附带一个session id的get形式传递了,当然也可以通过http post。

      session的使用

      首先,要用session_start()开启一个会话。注意对于这类网络函数,在它前面不准有输出,哪怕是<?php标识符前面有空格也不行(必须有输出可以用ob_start()控制,先输出到缓存 )。(注意,有时单独一句session_start()会报警告,后面会谈到)

      然后,注册会话变量,也就是存取用户信息或有用的数据,不需要使用什么函数,直接存入$_SESSION超全局数组,比如$_SESSION['user'] = $_POST[['user'],这些数据将被保存到服务端的某个文件中,当然也可能是缓存(memcache、redis)中。

      当跳转到其他页面时,在其他页面也要先开启这个会话,依然是session_start(),如果会话已经开启,该函数返回当前会话,如果没有则重新开启。

      最后,用户退出或某些原因销毁对话,要注销这些变量。分四步走:

      1.仍然是先开启会话,或者是跳转到其他页面时,再次返回已经存在的会话,需要确保前面没有输出

    session_start();   // 开启或返回一个会话

 

      2.清空$_SESSION数组中的相关变量

    unset($_SESSION['robert'])  // 销毁某一个变量
    $_SESSION = array();  // 或者一次性全部销毁会话变量

 

      3.清除保存在客户端的cookie,别忘了session id还在用户计算机上面

    if(isset($_COOKIE[session_name()])){
        unset($_COOKIE[session_name()]);    // session_name()获取sesion的名,session id也是以名和值的形式存储的
    }

      4.彻底销毁存储到服务器的信息

    session_destroy();

       四步走完,就结束了一次session会话。

       以上是简单的对php会话控制做一个小结,在实际编程中,可能会遇到其他问题。我就出现了以下问题:

       1、此网页包含重定向循环

       我自以为安全的设了一个检查用户是否登录的判断脚本,只要是一个脚本中就include它,想法是检测到没有登录就跳转到登录页面。问题是不要跳转到本页面,因为你本来就是访问本页面,然后又header跳转到本页面,这就是一个死循环了,浏览器可检测出来。

       2、警告:session已经在***脚本中开启

      前面说的只是简单session_start()就行,开启了就返回会话,书上也这么说,但是,实现的时候却不行,已经开启就意味着没必要重复开启,可以这样判断下

    if(!isset($_COOKIE[session_name()])){
        session_start();
    }

       如果已经开启,$_COOKIE中会有一个session id,所以检查有了就不开启。

       3.以URL GET形式传递session id时,session不在$_GET数组中

复制代码
    <form action="login.php?<?php echo session_name();?>=<?php echo session_id(); ?>" method="post"> 
        <table align="center" border="1">
        <tr>
           <td>username</td>
           <td><input type="text" name="username"  /></td>
       </tr>
       <tr>
           <td>password</td>
           <td><input type="password" name="password" /></td>
       </tr>
       <tr>
           <td colspan="2" align="center"><input type="submit" name="sub" value="login" /></td>
       </tr>
       </table>
    </form>
复制代码

       本意是通过表单简单的传个用户名和密码过去,在form的action属性提交到本页面,提交的时候在后面附带上session id,但注意,如果表单的提交方法method也定为get,则这个URL传递并不成功GET数组中没有这个session id,如果form表单的method提交方法定为post后,这时表单提交的action地址后面的get传参是成功的。不知道为什么原因,也问过,暂且记下吧。

       4.session没有成功销毁

       完全按照那销毁四步来的,检查数遍没有问题,可就是销毁不了,两次登录的session是一样的,除非关闭浏览器后重新登录,不知道是不是用的机子蛋疼,重启电脑吧,tm居然又正常了-_-

抱歉!评论已关闭.