ホームページ  >  記事  >  php教程  >  php会话控制-session [个人笔记]

php会话控制-session [个人笔记]

WBOY
WBOYオリジナル
2016-06-07 11:44:06942ブラウズ

以前的个人笔记,分享
1 什么是会话控制<br>     出现原因:http是无状态协议的,每次都是不同的服务器请求,无法维护两个请求事务之间的关系.<br>     会话控制:能够在网站中跟踪一个变量,通过对变量的跟踪,就可以使多个请求事物之间建立联系,根据授权和用户身份显示不同的内容,不同页面<br>     cookie:是服务器设置在客户端的文本文件,保存客户端得个人信息.<br> 2 会话跟踪技术<br>     1 隐藏表单域<br>     2 url重写<br>     3 cookie技术<br>     4 session技术<br>     <br>     隐藏表单技术:<br>         <input>,在gethuopost方法中指定指定有关消息的会话名称和值<br>         <br>     url(统一资源定位)重写:<br>         将唯一会话的id添加到url结尾,来进行标识<br>         http://www.lampbrother.net?id=1000<br>     cookie:将唯一的会话id存放在客户端<br>     session:将唯一的会话id存放在服务器端<br> 2 会话跟踪方式<br>     第一:通过url传递参数,使用超链接或者header()函数<br>     第二:使用隐藏表单域,提交给php脚本<br>     第三:使用Cookie将用户的信息存储在客户端文件中<br>     第四:使用Session将用户的信息存储在服务器端的信息存储在服务器端<br>     <br> 4 Cookie:<br>     1 Cookie的介绍:<br>         1 cookie是在http协议下,服务器或脚本在客户端保存维护信息的一种方式<br>         2 cookie是web服务器保存在客户端的一个很小的文本文件,保存客户端的信息,提高网页的处理效率,降低服务器负担<br>         3 cookie保存在客户端,通常在浏览器的cookie临时文件夹中,可以手动的删除.如果cookie太多超过系统的允许范围,系统将自动删除<br>     <br>     2 cookie的工作原理<br>          1 当用户访问基于php技术的网站时,在php中可以使用setcookie()函数生成一个cookie,系统经过处理,将cookie发送到客户端并保存在C:\Documents and Setting\用户名\Cookies目录下<br>         2 cookie是http标头的一部分,在它之前不能有任何输出空格和换行都不可以<br>         3 当客户端再次访问网站时,浏览器会自动把cookie目录下与该站点对应的cookie信息发送到服务器,服务器将自动把客户端传来的cookie转化成php的变量,.php5中存放在$_COOKIE全局数据中<br>         4 接受和处理cookie.使用$_COOKIE获取<br>     <br>         Setcookie()为头信息设置,在此之前不能有任何输出<br>         boolsetcookie( string $name [, string $value [, int $expire = 0 [, string $path [, string $domain [, bool $secure = false [, bool $httponly = false ]]]]]] )<br>         Name:调用名为cookiename的cookie <br>         value :name对应的值<br>         exprice :设置cookie的过期时间和日期,用一个标 准的Unix时间标记,可以用time()函数取得,以秒为单位. <br>         path :服务器端的有效路径,设置为“/”表示这个域中所有数组都可以被访问读取。 <br>         Domain:设定cookie有效域名 <br>         secure :指明cookie只能通过安全的https传送, 设为true时只能通过安全的https,默认为false.即设置是否仅在https安全连接时才发送cookie到客户端:0或 1<br>     <br>         删除cookie:<br>             1 调用一个参数名为已经存在的cookied的名称,则删除就会删除cookie<br>             2 设置cookie的失效时间为time()或者time()-1<br>     <br>         注意:当cookie被删除时,它的值在当前页面仍然有效.如果要把cookie设置成在浏览器关闭后就失效.那么可以吧expiretime的值设为0,或者不设此值<br>     <br>         /*设置cookie*/<br>         $time=time()+3600;//设置时间为一个小时<br>         //保存变量<br>         setcookie('username','admin',$time);<br>         setCookie('password','123456',$time);<br>     <br>         //保存数组<br>         setCookie("cookie[one]",'coo1',$time);<br>         setCookie("cookie[two]",'coo2',$time);<br>         /*删除cookie*/<br>         //方式1:设置值为空<br>         setCookie('username',"");<br>         setCookie('cookie[one]',"");<br>         //方式1:设置过期时间<br>         setCookie('password',"coo1",time()-1);<br>         setCookie('cookie[two]',"coo2",time()-1);<br>         if(isset($_COOKIE)){<br>         }<br>     3 COOKIE的注意事项<br>         1 setcookie()之前不能有任何的输出,空白和空格也不行(Setcookie()为头信息设置)<br>         2 setcookie()之后在当前页面echo时不会输出,必须刷新或到下一个页面才会输出<br>         3 不同浏览对cookie的处理不同,客户端可以禁用cookie,而且对浏览器的数量有限制.一个浏览器可以最多创建300个cookie,每个不能超过4kb,每个站点最多设置20个<br>         4 避免过度依赖cookie,因为客户端会禁止掉cookie<br>     <br> 7 session<br>     1 什么是session?<br>         1 session从用户访问页面开始,到断开与网站的连接为止,形成一个会话的生命周期.在会话期间,分配客户唯一的一个sessionID,用来标识当前用户,与其他用户进行区分<br>         2 session会话时,session会分别保存在客户端和服务器端得两个文职,对于客户端:使用临时的cookie保存(cookie的名称为PHPSESSID)或者通过url字符串的形式传递.服务器端也以文本的形式保存在指定的session目录中<br>         3 session通过id接受每一次访问的请求,从而识别当前用户,跟踪和保持用户的具体资料,以及session变量,可在session中国存储数字或文字资料.比如session_name.这些信息都保存在服务器端<br>         4 sessionID可以作为会话信息保存到数据库中,进行session持久化.这样可以跟踪用户的登陆次数,在线与否,在线时间<br>     2 cookie和session的区别:<br>         相同点:都可以在解决http无状态的问题,使同一个客户端在访问网站的多次请求中,可以保存,设置信息,并且在整个web应用中共享<br>         <br>         不同:<br>         cookie的信息保存在客户端<br>         session:保存在服务器端<br>     <br>         联系:当使用基于cookie的session时,session DI一般保存在cookie中<br>     3 设置session<br>         1 开启会话<br>             session_start()        功能 : 1开始一个会话,2 返回已经存在会话<br>             说明:这个函数没有参数,且返回值为true,如果使用基于cookie的sessin,那么在session_satrt()之前不能有任何的输出,包括空白<br>     <br>         2 注册会话<br>             php5 使用$_SESSION['KEY']=VALUE方式,类似于GET,POST,COOKIE<br>     <br>         3 使用会话之前必须session_start()启动会话,这样就可以使用$_SEESION超全局数组访问变量了<br>             判断是否设置session<br>             if(isset($_SESSION))...;<br>         <br>         如果在php.ini中session.auto_start=1;开启,则在每个页面执行session_start(),不需要手工设置.<br>         缺点:不能将对象放入session中<br>         <br>         //开启一个session会话,或者返回已经存在的session<br>         session_start();<br>         //这只session<br>         $_SESSION['USER']='admin';<br>         $_SESSION['username']='admin_root';<br>         //获得session_id()<br>         //1 PHPSESSID<br>         echo $_COOKIE['PHPSESSID'].'<br>';<br>         //2 session_name()<br>         echo $_COOKIE[session_name()].'<br>';<br>         //3 session_id()<br>         echo session_id().'<br>';<br>     4 销毁session<br>         <br>         注销变量:<br>             1 unset($_SESSION['XXX']):用于删除单个session变量<br>                 注意:不要使用unset($_SESSION),此函数不可用,会删除全局的$_SESSION销毁<br>         <br>             2 $_SESSION=array():删除多个session变量<br>             3 session_unset():删除所有的session变量<br>         销毁session_destroy():结束当前的会话,并清空会话中的所有资源.该函数不会unset(释放)和当前session相关的全局变量,也不会删除客户端的session cookie<br>                 //返回已经存在的session<br>                 session_start();<br>     <br>                 //清空session值<br>                 $_SESSION=array();<br>     <br>                 //如果是基于Cookie的session,则清空cookie中的session_id()<br>                 if(isset($_COOKIE[session_name()])){<br>                     //  '/':在php.ini中年的cookie.path='/';<br>                     setCookie($_COOKIE[session_name()],'',time()-3600,'/');<br>                 }<br>                 //销毁session<br>                 session_destroy();<br>             注:php默认的session是基于cookie的,如果要删除cookie的话,必须借助setcookie()函数<br>         <br>     5 保存session数据<br>         1 保存基本数据类型<br>         2 保存数组<br>         3 保存对象<br>         session_start();<br>         //存取标量<br>         $_SESSION['USER']='ADMIN';//STRING<br>         $_SESSION['COUNT']=10;//INT<br>         $_SESSION['PRICE']=99.99;//FLOAT<br>         $_SESSION['IS_GOOD']=true;//BOOLEAN<br>         //存取数组<br>         $_SESSION['USER_INFO']=array('username'=>'root','password'=>123456);<br>         //存取对象<br>         class Person{public $name='admin';public $age=23;    }<br>         $_SESSION['OBJ']=new Person;<br>         <br>         函数:<br>         1 session_id():用于获取或取得当前的session的唯一标识符号SID,php5中既可以附加载url取得当前会话的session_id和session_name<br>             SID:即使是一个字符串session_name()=session_id();<br>             解释:<br>             a 如果session_id()有具体指定的值得话,将取代当前的session_id值.当cookie没有被禁用时,如果指定了一个session_id()值,每次启动session_start()都会网客户端发送一个cookie值.不论当前SESSION_ID值是否与指定值相等<br>             b 如果session_id()没有指定的值,则返回当前的SESSIONID,当前会话没有开启则返回空字符串<br>             c 使用该函数必须在session_start()之前<br>             <?php <br />                 //在session_start()之前设置session_id()<br>                 session_id('lamp');<br>                 session_start();<br>                 echo '当前的session_id()为:'.session_id().'<br>';//输出lamp<br>             ?><br>         <br>         2 session_regenerate_id():该函数更换当前的session_id,但不改变当前的session信息<br>             返回值:bool型<br>             session_id:命名规则[a-z, A-Z, 0-9 and '-,' ]<br>             //设置session_id=old_session[a-z, A-Z, 0-9 and '-,' ]<br>             session_id('old-session');<br>             $old_session_id=session_id();<br>     <br>             session_start();<br>             //更改session_id=new_session<br>             session_regenerate_id('new-session');<br>             $new_session_id=session_id();<br>             $_SESSION['USER']='ADMIN';//STRING<br>             echo '原来的session_id:'.$old_session_id.'<br>';<br>             echo '新的的session_id:'.$new_session_id.'<br>';<br>             print_r($_SESSION);<br>         3 session_name():获取或者更改当前的session_name,注意:不能只有数字组成,必须至少包含一个字母,否则每时每刻会生成新的session_id<br>         <br>             注意: session_id()和session_name()都要在session_start()之前设置<br>             session_id('lamp2012');<br>             session_name('mySession');<br>             session_start();<br>             $_SESSION['USER']='ADMIN';//STRING<br>             echo 'session_id:'.session_id().'<br>';<br>             echo 'session_name:'.session_name().'<br>';<br>             print_r($_SESSION);<br>          <br>     6 session跨页传递的三种问题:<br>         1 客户端禁用了cookie<br>         2 浏览器出现了问题无法存储cookie<br>         3 php.ini中的session.user_trans_sid=0或者编译时没有打开--enable-trans-sid选项<br>         解决的三条途径:<br>         1 在php.ini中开启session.user_trans-sid=1,或者编译时打开--enable-trans-sid选项,让php自动跨页传递session_id<br>         2 手动通过url传值,隐藏表单传递session_id<br>             <a>">sid</a><br>             <a>">sid</a><br>         3 用文件,数据库等形式保存sessin_id,在跨页过程中手工调用<br>             <br>     7 持久化session<br>         1 请求结束后所有的注册变量都会自动被序列化(为了方便保存到服务器端得会话文本文件中),获取的时候在进行还原<br>         手动编码:<br>         session_encode():序列号-编码<br>         session_decode():还原-解码<br>         <br>         警告:有些类型的数据不能被序列化因此也就不能保存.包括resource变量和有循环引用的对象<br>     9 配置会话控制<br>         session.auto_start=0;//在请求启动时初始化<br>         session.auto_start=0;//无需每次手动sessin_start(),不过该选项有一些限制,不能将对象放入会话,因为类的定义必须在会话之前加载在会话中重建对象<br>         session.cache_expire=180;//设置缓存中的会话过期时间在n分钟后<br>         session.cookie_lifetime=0;//设置按秒记的cookie的保存时间,0表示知道浏览器被重启<br>         session.cookie_path=/;//cookie的有效路径<br>         session.cookie_domain=;//cookie的有效域<br>         session.name=PHPSSESID;//又在cookie里的session_name()<br>         session.save_hander=files;//用于保存/取回数据的控制方式<br>         session.save_path=/tmp;//在save_handler设为文件是传给控制器的参数,这是数据文件的保存路径<br>         session.user_cookie=1;//是否使用cookies<br>         <br>         session.gc_maxlifetime=40;//指定过了多少秒之后数据就会被视为“垃圾”,并被清楚<br>     <br>         session.gc_probability=1//<br>         session.gc_divisor=100;//这两个合起来就是启动gc进程管理概率的,在session初使化时(session_start())<br>             session.gc_probability/session.gc_divisor:1/100,在session_start100次,有一次的概率删除垃圾文件<br>     10 用文件保存session信息<br>         1: 将php.ini中的session.save_handler的cookie保存方式选项user    <br>         2: 设置session操作中的回调函数,在session_start()之前使用session_set_save_handler('open','close','read','write','destroy','gc');<br>         3: 开启session_start();<br>             函数解析:<br>             open($session_path,$session_name):在session_start()时启动,返回true<br>             close():session_close()和session_destroy()时调用,return true<br>             read($session_id):session_start()时和从$_SESSION取值的时调用,return true<br>             write($session_id,$session_data):在session_write_close()强制将数据写入到$_SESSION全局数组中时调用,return true;<br>             destroy($session_id):在执行session_destroy()自动调用,return true<br>             gc($session_gc_lifetime):在执行session_start().read(),write()时自动调用,return true<br>         <br>         //参数:$save_path,$session_name<br>         function open($save_path, $session_name){<br>             //设置全局的session信息保存路径<br>             global $sess_save_path;<br>             //为session的保存路径赋值<br>             $sess_save_path=$save_path;<br>             return true;<br>         }<br>         //session_write_close()和session_destroy()时调用<br>         function close(){<br>             //在销毁和关闭写入时,不进行任何操作,返回true<br>             return true;<br>         }<br>         //在session_start(),$_SESSION,将session数据读取到$_SESSION中时<br>         //参数:session_id<br>         function read($id){<br>             //获得全局的session保存路径<br>             global $sess_save_path;<br>             //拼接所需的文件路径名称<br>             $sess_file=$sess_save_path.'/king_'.$id;<br>             //返回文件的信息,没有文件时返回false<br>             return    (string)@file_get_contents($sess_file);<br>         }<br>         //结束时和session_write_close()强制将SESSION数据防止在$_SESSION全局变量时<br>         function write($id,$sess_data){<br>         <br>             global $sess_save_path;<br>             $sess_file=$sess_save_path.'/king_'.$id;<br>             //以w模式打开文件<br>             if($fp=@fopen($sess_file,'w')){<br>                 将session信息写入指定的资源中<br>                 $return=fwrite($fp,$sess_data);<br>                 fclose($fp);<br>                 return $return;<br>             }else{<br>                 return false;<br>             }<br>         }<br>         //在destroy时调用<br>         function destroy($id){<br>             global $sess_save_path;<br>             $sess_file=$sess_save_path.'/king_'.$id;<br>             //删除session路径下指定的session信心<br>             return @unlink($sess_file);<br>         }<br>         //在session_start(),read(),write()时<br>         function gc($maxlifetime){<br>             global $sess_save_path;<br>             //glob — 寻找与模式匹配的文件路径,返回数组<br>             //将路径写的所有超过gc生命周期的文件删除<br>             foreach(glob($sess_save_path.'/king_*') as $filename){<br>                 if(filemtime($filename)+$maxlifetime                      @unlink($filename);<br>                 <br>                 }<br>             }<br>                 return true;<br>         }<br>         @session_set_save_handler('open','close','read','wite','destroy','gc');<br>         @session_start();<br>     11 将session信息保存到数据库<br>         sql:测试表<br>         create table session(<br>             PHPSSESID char(32),    //session_id<br>             update_time int(10),    //文件的gc_maxlifetime<br>             client_ip char(15),    //客户端ip地址<br>             data text)    //session信息<br>         1:设置session.save_handler=user;//自定义session存储方式<br>         2 session.gc_maxlifetime=time;//gc回收垃圾的时间<br>         3 在session_start()之前调用session_set_save_handler('open','close','read','write','destroy','gc');<br>         4 写session处理类,静态属性和方法<br>         5 开启session_start();<br>         <?php <br />             //session_set_save_handler<br>             class Session{<br>                 private static $handler=null;//传进来的pdo句柄<br>                 private static $client_ip=null;//客户端ip<br>                 private static $lifetime=null;//生存时间(session.gc_maxlifetime)<br>                 private static $time;//访问时的时间戳<br>                 //设置初始化参数<br>                 private static function init($handler){<br>                     self::$handler=$handler;<br>                     self::$client_ip=!empty($_SERVER['REMOTE_ADDR'])?$_SERVER['REMOTE_ADDR']:"unKnown";//设置客户端的ip地址<br>                     self::$lifetime=ini_get('session.gc_maxlifetime');//gc回收垃圾的最大生命周期<br>                     self::$time=time();<br>                 }<br>                 //设置自定义的session处理方式,并开启session_start()<br>                 public static function start(PDO $pdo){<br>                     <br>                     self::init($pdo);//设置当前使用的pdo句柄<br>                     //__CLASS__:php起,返回类的名称<br>                     session_set_save_handler(<br>                         array(__CLASS__,'open'),<br>                         array(__CLASS__,'close'),<br>                         array(__CLASS__,'read'),<br>                         array(__CLASS__,'write'),<br>                         array(__CLASS__,'destroy'),<br>                         array(__CLASS__,'gc')<br>                     <br>                     );<br>                     //开启session<br>                     session_start();<br>                 }<br>                 //open处理方法,不进行任何操作,返回true<br>                 public static function open($session_path,$session_name){<br>                     return true;<br>                 }<br>                 //close处理方法,不进行任何操作,返回true<br>                 public static function close(){<br>                     return true;<br>                 }<br>                 //读取session数据的操作<br>                 public static function read($session_id){<br>                     $sql='select update_time,client_ip,data from session where PHPSSESID="'.$session_id.'"';<br>                 <br>                     $stmt=self::$handler->prepare($sql);<br>                     $stmt->execute(array($session_id));<br>                     $result=$stmt->fetch(PDO::FETCH_ASSOC);<br>                     //没有查询结果返回:''<br>                     if(!$result){<br>                         self::destroy($session_id);<br>                         return "";<br>                     }<br>                     //ip地址有误返回:''<br>                     if($result['client_ip'] != self::$client_ip){<br>                         self::destroy($session_id);<br>                         return '';<br>                     }<br>                     <br>                     //数据合法返回数据<br>                     return $result['data'];<br>                 }<br>                 //写入数据库<br>                 public static function write($session_id,$session_data){<br>                     <br>                     $sql_select='select PHPSSESID,update_time,client_ip,data from session where PHPSSESID="'.$session_id.'"';<br>                     $stmt=self::$handler->prepare($sql_select);<br>                     $stmt->execute();<br>                 <br>                     //数据已经存在记录则更新<br>                     if($result=$stmt->fetch(PDO::FETCH_ASSOC)){<br>                         <br>                         if($result['data'] != $session_data || self::$time > ($result['update_time']+10)){<br>                             $sql_update='update sessoin set update_time=?,data=? where PHPSSESID="'.$session_id.'"';<br>                             <br>                             $stmt_update=self::$handler->prepare($sql_update);<br>                             if($stmt_update->execute(array(self::$time,$session_data))){<br>                                 return true;<br>                             }<br>                         }<br>                     }else{<br>                         <br>                         //数据不存在记录则插入记录<br>                         if(!empty($session_data)){<br>                             $sql_insert='insert into session(PHPSSESID,update_time,client_ip,data) values(?,?,?,?)';<br>                             $stmt_insert=self::$handler->prepare($sql_insert);<br>                             if($stmt_insert->execute(array($session_id,self::$time,self::$client_ip,$session_data))){<br>                                 return true;<br>                             }<br>                         }<br>                     <br>                     }<br>                 }<br>                 //调用该方法删除指定的session信息<br>                 public static function destroy($session_id){<br>                     $sql='delete from session where PHPSSESID="'.$session_id.'"';<br>                     $stmt=self::$handler->prepare($sql);<br>                     if($stmt->execute(array($session_id))){<br>                         return true;<br>                     }<br>                 }<br>                 //超过最大生命周期的时候删除数据<br>                  static function gc($session_gc_maxlifetime){<br>                      $sql="delete from session where update_time ";<br>                     <br>                     $stmt=self::$handler->prepare($sql);<br>                     $stmt->execute(array(self::$time-$session_gc_maxlifetime));<br>                 <br>                     return true;<br>                 <br>                 }<br>             }<br>             try{<br>                 $pdo=new PDO('mysql:host=localhost;dbname=demo;charset=utf8','root','123456');<br>             }catch(PDOException $e){<br>                 echo $e->getMessage();<br>             }<br>             Session::start($pdo);<br>             <br>         ?><br>     12 session保存在memcache中<br>         <br>     <br>                 <?php <br />             class MemSession {<br>                 private static $handler=null;<br>                 private static $lifetime=null;<br>                 private static $time = null;<br>                 const NS='session_';<br>                 <br>                 private static function init($handler){<br>                     self::$handler=$handler;<br>                     self::$lifetime=ini_get('session.gc_maxlifetime');<br>                     self::$time=time();<br>                 }<br>                 public static function start(Memcache $memcache){<br>                     self::init($memcache);<br>                     session_set_save_handler(<br>                             array(__CLASS__, 'open'),<br>                             array(__CLASS__, 'close'),<br>                             array(__CLASS__, 'read'),<br>                             array(__CLASS__, 'write'),<br>                             array(__CLASS__, 'destroy'),<br>                             array(__CLASS__, 'gc')<br>                         );<br>                     session_start();<br>                 }<br>             <br>                 public static function open($path, $name){<br>                     return true;<br>                 }<br>                 public static function close(){<br>                     return true;<br>                 }<br>                 public static function read($PHPSESSID){<br>                     $out=self::$handler->get(self::session_key($PHPSESSID));<br>                     if($out===false || $out == null)<br>                         return '';<br>                     return $out;<br>                 }<br>                 public static function write($PHPSESSID, $data){<br>                     <br>                     $method=$data ? 'set' : 'replace';<br>                     return self::$handler->$method(self::session_key($PHPSESSID), $data, MEMCACHE_COMPRESSED, self::$lifetime);<br>                 }<br>                 public static function destroy($PHPSESSID){<br>                     return self::$handler->delete(self::session_key($PHPSESSID));<br>                 }<br>                 public static function gc($lifetime){<br>                     return true;<br>                 }<br>                 private static function session_key($PHPSESSID){<br>                     $session_key=self::NS.$PHPSESSID;<br>                     return $session_key;<br>                 }    <br>             }<br>             $memcache=new Memcache;<br>             $memcache->connect("localhost", 11211) or die("could not connect!");<br>             

AD:真正免费,域名+虚机+企业邮箱=0元

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。