COOKIE 和 SESSION

思考:A页面中如何访问B页面中的变量
包含文件
get传递或post传递
cookie:cookie是小的信息包。

Cookie

cookie的原理

浏览器—-http请求(无值)——–>服务器
浏览器<—响应头中传递cookie——-服务器
浏览器—-再次发送http请求(有值)–>服务器

  1. 请求头:客户端请求服务器的时候,告知服务器客户端的信息
  2. 响应头:服务器响应客户端的时候,告知客户端服务器的信息

长连接

在多个http请求之间,TCP连接不断开称为长连接,默认是5秒。
长连接过程中,可以建立多次http请求http响应

cookie保存在客户端

设置cookie

语法:setcookie(名字,值,过期时间,有效目录,子域名)

bool setcookie ( string $name [, string $value = "" [, int $expire = 0 [, string $path = "" [, string $domain = "" [, bool $secure = false [, bool $httponly = false ]]]]]] )

临时性cookie

关闭浏览器cookie就消失

永久性cookie

  • [ ] 下次自动登录 (案例)

在临时性cookie的基础上加上一个过期时间就成了永久性cookie,过期时间是一个时间戳
永久性cookie保存在浏览器上,换个浏览器就不行了

cookie保存的数据类型

cookie不能存放bool型数据,true=>1 false=>delete
cookie不能存放数组和对象
cookie中只能存放字符串

删除cookie

1
2
3
4
5
6
7
Set-Cookie:
name=uiste; expires=Mon, 26-Sep-2015 12:07:11 GMT; Max-Age=100
sex=man; expires=Mon, 26-Sep-2015 12:07:11 GMT; Max-Age=100
age=24; expires=Mon, 26-Sep-2015 12:07:11 GMT; Max-Age=100
name=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0
sex=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0
age=

cookie支持下标

cookie在浏览器上没有数组的概念,只是浏览器请求到服务器,PHP将同名的变量转成数组

1
2
3
4
5
6
<?php
//cookie不支持数组,但是支持下标
setcookie('stu[0]','tom');
setcookie('stu[1]','berry');
setcookie('stu[2]','ketty');
?>

cookie有效目录

默认情况下,cookie只能在当前目录和子级目录中有效
如果要在整个网站中有效,就要设置有效目录,‘/’表示整站有效
setcookie('name','tom',0,'/')

cookie支持子域名

默认情况下,cookie是区分子域名的。一个子域名就代替一个独立的服务器

cookie的缺点

  1. 信息保存在本地,安全性低
  2. 只能保存字符串,不能保存数组和对象,可控性差
  3. 数据保存在头信息中,增加请求时的数据负载
  4. 一般浏览器对cookie的要求是不能高于4K

session(会话)

将数据存储到服务器端,每个客户一个空间,通过编号访问自己的数据

  • 第一次访问服务器,服务器给客户端分配一个编号
  • 通过编号来访问服务器保存的数据
  • 每个客户只能访问自己的数据
    session是基于cookie的技术

session的操作

  1. 要使用会话必须显示的开启会话,session_start()。默认情况下,会话不会自动开启。
  2. 要自动开启会话,在php.ini文件中session.auto_start=1,把0改为1就自动开启了
  3. session_id():会话编号
  4. session_name():会话名称
  5. session可以保存除了资源以外的所有类型的数据
  6. 重复开启会话会报错,可以通过@来屏蔽会话

session执行过程

  1. 使用session_start()session仓库中加载已经存在的session变量
  2. 第一次请求服务器,一个唯一的会话id存储到cookie响应头中
  3. 在后面的请求中,会话id保存请求头中,服务器获取请求头的会话id,通过id获取会话的值
  4. 页面执行完毕返回到客户端之前,将会话自动保存到服务器的session库中。下次浏览网页可以加载再次使用

session的配置

  1. session.save_path:指定session库的路径

session.save_path = “N;/path”, N表示通过N级目录来保存会话,N等于1,就是通过会话的第一个字母创建文件夹;N等于2表示通过两级目录创建文件夹,第一级是第一个字母,第二级是第二个字母。

1
2
3
4
5
; 用于保存/取回数据的控制方式
session.save_handler=files
; session.save_path = "N;/path"
; 在 save_handler 设为文件时传给控制器的参数, 这是数据文件将保存的路径
session.save_path="/Applications/XAMPP/xamppfiles/temp/"
  1. session.name:设置会话名称

1
2
3
; Name of the session (used as cookie name).
; http://php.net/session.name
session.name=PHPSESSID
  1. session.cookie_lifetime:保存会话编号的cookie有效时间

1
2
3
; Lifetime in seconds of cookie or, if 0, until browser is restarted.
; http://php.net/session.cookie-lifetime
session.cookie_lifetime=0
  1. session.cookie_path:保存会话的cookie整站有效

1
2
3
; The path for which the cookie is valid.
; http://php.net/session.cookie-path
session.cookie_path=/
  1. session.cookie_domain:当前域名有效

1
2
3
; The domain for which the cookie is valid.
; http://php.net/session.cookie-domain
session.cookie_domain=
  1. session.save_handler = files:会话按文件格式保存

1
2
3
; Handler used to store/retrieve data.
; http://php.net/session.save-handler
session.save_handler=files
  1. session.hash_function = 0:设置session会话的算法

1
2
3
4
5
6
; Select a hash function for use in generating session ids.
; Possible Values
; 0 (MD5 128 bits)
; 1 (SHA-1 160 bits)
; http://php.net/session.hash-function
session.hash_function=0
  1. session.hash_bits_per_character = 5:每个字符占用的位数

1
2
3
4
5
6
7
8
9
10
11
; Define how many bits are stored in each character when converting
; the binary hash data to something readable.
; Possible values:
; 4 (4 bits: 0-9, a-f)
; 5 (5 bits: 0-9, a-v)
; 6 (6 bits: 0-9, a-z, A-Z, "-", ",")
; Default Value: 4
; Development Value: 5
; Production Value: 5
; http://php.net/session.hash-bits-per-character
session.hash_bits_per_character=5
  1. session.gc_maxlifetime = 1440:会话过期时间

1
2
3
4
; After this number of seconds, stored data will be seen as 'garbage' and
; cleaned up by the garbage collection process.
; http://php.net/session.gc-maxlifetime
session.gc_maxlifetime=1440

session_destroy():销毁会话

  1. 删除储存介质中的文件
  2. 执行此行,就不会执行会话写入操作了

session入库

新建数据库

1
2
3
4
5
6
drop table if exists sess;
create table sess(
sess_id varchar(32) primary key comment '会话编号',
sess_value text comment '会话的值',
sess_expires int not null comment '会话产生时间'
)engine=innodb charset=utf8;

session_set_save_handler()设置用户自定义会话存储函数

bool session_set_save_handler ( callable $open , callable $close , callable $read , callable $write , callable $destroy , callable $gc [, callable $create_sid ] )

  • open:开启会话
  • close:关闭会话
  • read:读取会话
  • write:写入会话
  • destroy:销毁会话
  • gc:销毁会话

执行session_destroy()的时候才调用destroy()函数

为什么gc不执行?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
; Defines the probability that the 'garbage collection' process is started
; on every session initialization. The probability is calculated by using
; gc_probability/gc_divisor. Where session.gc_probability is the numerator
; and gc_divisor is the denominator in the equation. Setting this value to 1
; when the session.gc_divisor value is 100 will give you approximately a 1% chance
; the gc will run on any give request.
; Default Value: 1
; Development Value: 1
; Production Value: 1
; http://php.net/session.gc-probability
session.gc_probability=1

; Defines the probability that the 'garbage collection' process is started on every
; session initialization. The probability is calculated by using the following equation:
; gc_probability/gc_divisor. Where session.gc_probability is the numerator and
; session.gc_divisor is the denominator in the equation. Setting this value to 1
; when the session.gc_divisor value is 100 will give you approximately a 1% chance
; the gc will run on any give request. Increasing this value to 1000 will give you
; a 0.1% chance the gc will run on any give request. For high volume production servers,
; this is a more efficient approach.
; Default Value: 100
; Development Value: 1000
; Production Value: 1000
; http://php.net/session.gc-divisor
session.gc_divisor=1000

session.gc_probability=1 概率
session.gc_divisor=1000 除数
执行垃圾回收的概率是:1/1000

session入库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<?php
header('content-type:text/html;charset=utf-8');
//开启会话
function open() {
mysql_connect('localhost','root','aa');
mysql_query('set names utf8');
mysql_query('use php5');
}
//关闭会话
function close() {
}
/**
*读取会话
*@param $sess_id string 会话编号
*/
function read($sess_id) {
$sql="select sess_value from sess where sess_id='$sess_id'";
$rs=mysql_query($sql);
if($rows=mysql_fetch_row($rs))
return $rows[0];
return '';
}
/**
*写入会话
*@param $sess_id string 会话编号
*@param $sess_value string 会话值
*/
function write($sess_id,$sess_value) {
$expires=time();
$sql="insert into sess values ('$sess_id','$sess_value',$expires) on duplicate key update sess_value='$sess_value',sess_expires=$expires";
return mysql_query($sql);
}
/**
*销毁会话
*/
function destroy($sess_id) {
$sql="delete from sess where sess_id='$sess_id'";
return mysql_query($sql);
}
/**
*垃圾回收
*超过生命周期的会话都是垃圾
*/
function gc($maxlifetime) {
$time=time()-$maxlifetime;
$sql="delete from sess where sess_expires<$time";
return mysql_query($sql);
}

//更改会话的存储
session_set_save_handler('open','close','read','write','destroy','gc');
session_start();
$_SESSION['sex']=100;
echo $_SESSION['sex'];
session_destroy();
?>

session_set_save_handler()必须放在session_start()前面才能起作用

COOKIE 与 SESSION的区别

cookie将键值存储在浏览器上
session将键存储在浏览器上,值存储在服务器上。

cookie的可以被禁用的,禁用cookie,基于cookie的所有技术都无法使用。

默认情况下,session是基于的cookie的,可以通过配置更改。

session.use_trans_sid=1
session.use_only_cookies=0

重启Apache会发现,会话编号不保存到cookie中,而是保存到get提交的URL中或表单的隐藏域中。

已知session_set_save_handler()必须在session_start()前面开启,如果在php.ini中设置了session.auto_start = 1后,则session_set_save_handler()无效。如何处理?
在分布式部署文件中有两个指令来更改php.ini中的配置
php_flag:用来更改开关性质的配置
php_value:用来更改值性质的配置
php_flag session.auto_start 0
php_value session.gc_maxlifetime 10
将以上命令添置在.htaccess文件中