|
首先,Session是基于cookie的,由于cookie保存在客户端,数据不安全。而Session可以理解为是将cookie保存在服务器上。
Session的原理如下:
- 1、客户端第一次访问服务器时,服务器会给每一个客户端分配一个空间,并为每个空间分配唯一的编号。
- 2、服务器将这个编号通过响应头作为cookie值响应给客户端。
- 3、客户端再次访问时会自动在请求头中携带该cookie传给服务器。
复制代码
默认情况下服务器不自动分配session会话,需要手动开启。代码如下:
- session_start();//开启session会话
复制代码
设置与获取session的方法如下:
- $_SESSION['name']='zhangsan';//设置session
- $_SESSION['age']=18;//设置session
- echo $_SESSION['name']."<br>";//获取session
- echo $_SESSION['age']."<br>";//获取session
复制代码 执行以上代码,浏览器输出结果如下:
服务器获取session编号,代码如下:
- session_start();//开启session会话
- $_SESSION['name']='zhangsan';//设置session
- $_SESSION['age']=18;//设置session
- echo $_SESSION['name']."<br>";//获取session
- echo $_SESSION['age']."<br>";//获取session
- echo 'session会话编号'.session_id();
复制代码
执行结果如下:
注意:session_start();只能开启一次,如果require文件中有session_start();语句,请在require文件中这样写:@session_start();
PHP.ini中与session相关的配置:
1、session.save_handler = files //session文件类型
2、session.save_path="D:\wamp\PHPTutorial\tmp\tmp" //session文件保存位置,默认由操作系统分配
如果修改该地址为:Y:\Code Archives\session,那么就会在该文件夹下保存session文件,如下:
默认情况下,关闭浏览器后session信息立即失效,但服务器不会删除session会话文件,重新打开浏览器后服务器再次写出session文件,并分配编号。
3、session.auto_start = 0 //是否自动开启session会话,0为不开启 1为开启。一般情况下都是设置为0,通过php代码手动开启。
4、session.gc_maxlifetime = 1440 //session文件空间的生命周期,默认为1440秒=24分钟,超过该时间后session文件被释放。
5、session.name = PHPSESSID //session的字段名称
6、session.cookie_lifetime = 0 //session编号的过期时间 0表示关闭浏览器即失效,其它数字为秒数。
7、session.cookie_path = / //session的有效范围,默认为整站有效
8、session.cookie_domain = //模式在当前域名下有效
注意:当前页面执行完毕后会自动关闭session会话,其它页面在获取session前需再次打开session文件空间,否则无法获取数据。例如,从session.php文件跳转至session2.php文件,那么在session2.php中应该这样写:
- <?php
- session_start();//再次打开session文件空间
- echo $_SESSION['name']."<br>";//获取session
- echo $_SESSION['age']."<br>";//获取session
- ?>
复制代码 执行效果如下:
销毁会话:执行如下代码将删除session会话文件。
执行效果如下:
session会话的缓存文件由PHP的垃圾回收机制自动清理,回收的判断依据是session文件空间的生命周期设置,即php.ini中的session.gc_maxlifetime = 1440。
但是,超过这个时间后,PHP并不会立即全部过期文件,而是由php.ini中的session.gc_probability = 1和session.gc_divisor = 1000决定,这两句代码的意思是:回收的概率为1000分之1,即:触发1000次回收机制,才删除一次。
由于session是基于cookie的,默认情况下,当客户端阻止cookie后,session便不能使用。可以在php.ini中设置如下两个配置。
- session.use_only_cookies = 0 //表示session不仅依赖cookie
- session.use_trans_sid = 1 //表示允许通过其它方式传递sessionID
复制代码 设置以后会在GET请求地址中自动将sessionID作为参数传送给服务器,点击链接跳转后服务器自动接收sessionID。如下:
设置以后会在form表单中自动加入一个隐藏的input标签,value值是sessionID,如下:
在发送post请求时,服务器自动接收该sessionID,与get同理。
当然,session的强大还远不止于此,我们还可以将session保存到数据库中。
首先,我们创建一张数据表,sql代码如下:
- 方式一:innodb引擎方式(速度慢,永久保存)
- drop table if exists session;
- create table session (
- session_id varchar(50) primary KEY comment '会话编号',
- session_value text comment '会话值',//如果使用text类型,引擎就不能使用memory,数据只能存储在磁盘中
- session_time int unsigned not null comment '会话产生时间'
- )engine=innodb charset=utf8 comment '会话表'
复制代码- 方式二:memory引擎方式(速度快,重启数据库清空)
- drop table if exists session;
- create table session (
- session_id varchar(50) primary KEY comment '会话编号',
- session_value varchar(2000) comment '会话值',
- session_time int unsigned not null comment '会话产生时间'
- )engine=memory charset=utf8 comment '会话表'
复制代码
写入数据的PHP代码如下:
- <?php
- //打开会话
- function open() {
- global $link;
- $link=mysqli_connect('localhost','root','root','data');
- mysqli_set_charset($link,'utf8');
- return true;
- }
- //关闭会话
- function close() {
- return true;
- }
- //读取会话
- function read($session_id) {
- global $link;
- $sql="select session_value from session where session_id='$session_id'";
- $rs=mysqli_query($link,$sql);
- $rows=mysqli_fetch_row($rs);
- return (string)$rows[0];
- }
- //写入会话
- function write($session_id,$session_value) {
- global $link;
- $sql="insert into session values ('$session_id','$session_value',unix_timestamp()) on duplicate key update session_value='$session_value',session_time=unix_timestamp()";
- return mysqli_query($link,$sql);
- }
- //销毁会话
- function destroy($session_id) {
- global $link;
- $sql="delete from session where session_id='$session_id'";
- return mysqli_query($link,$sql);
- }
- //垃圾回收
- function gc($lifetime) {
- global $link;
- $expires=time()-$lifetime; //过期时间点
- $sql="delete from session where session_time<$expires";
- return mysqli_query($link,$sql);
- }
- //更改会话存储
- session_set_save_handler('open','close','read','write','destroy','gc');
- //开启会话
- session_start();
- //session_destroy();
- $_SESSION['stu']=['tom','berry','hot'];
复制代码 注意:这一步有很多人出错,且极难找到问题。PHP会报如下错误,网上的解决方案几乎全部是胡扯,这是一个深坑。
错误信息:Warning: Failed to write session data (files).Please verify that the current setting of session.save_path is correct () in Unknown on line 0
PHP的该提示害人不浅,它说是保存位置的问题,其实写入数据时,主键冲突的问题。解决方法如下:
写入会话的sql语句应该这样写:意思是:如果sessionid已经存在则执行更新语句。
- $sql="insert into session values ('$session_id','$session_value',unix_timestamp()) on duplicate key update session_value='$session_value',session_time=unix_timestamp()";
复制代码
读取数据库中的session,代码如下:- echo $_SESSION['name'];
- print_r($_SESSION['stu']);
复制代码 结果如下:
以上就是session的全部。 |
|