session和cookie的最大区别在于session是保存在服务端的内存中,
而cookie保存与浏览器或客户端文件里面;
session是基于访问的进程,记录了一个访问的开始到结束,当浏览器或进程关闭以后,session也就消失了。
而cookie更多地用于标示用于,可以长久的,用于用户跟踪和识别唯一用户。
===========
关于session,被用于表示一个持续的链接状态,在网站访问中一般代指client 浏览器从开启到结束的过程。
session其实就是网站分析的访问visits变量,表示一个访问的过程。
浏览器区域多进程的session共享:通过多个标签或页面多个进程访问同一网站时同享一个session cookie,只有当浏览器被关闭时才会被清除,就是你有可能在标签中关闭了丐网站,但只要浏览器未被关闭并且服务器的session未失效前重新开启该网站,那么就是使用session进行浏览。
http://www.biaodianfu.com/session-and-cookie.html
===================
session是一种基于http协议的用以增强web应用能力的机制或者说一种方案,不是单指某种特定的动态页面技术,而这种能力就是保持状态(保持绘画)。
在许多动态网站的开发者看来,session就是一个变量,而且其表现像个黑洞,他只需要将东西在合适的时机放进这个洞里,等需要的时候再把东西取出来。这是开发者对session最直观的感受,但是黑洞里的景象或者说session内部到底是怎么工作的呢?
在许多动态网站的开发者看来,session就是一个变量,而且其表现像个黑洞,他只需要将东西在合适的时机放进这个洞里,等需要的时候再把东西取出来。这是开发者对session最直观的感受,但是黑洞里的景象或者说session内部到底是怎么工作的呢?
web应用是基于HTTP协议的,而HTTP协议是一种无状态协议。也就是说,用户从A页面跳转到B页面会重新发送一次HTTP请求,而服务端在返回响应的时候是无法获知该用户在请求B页面之前做了什么的。解决HTTP协议自身无状态的方式有cookie和session。二者都能记录状态,前者是将状态数据保存在客户端,后者则保存在服务端。
关于Cookie的介绍可以查看这两篇文章:Cookie简介或Cookie与Session的区别。今天主要讲的是Session的实现原理。
session的基本原理是服务端为每一个session维护一份会话信息数据,而客户端和服务端依靠一个全局唯一的标识来访问会话信息数据。用户访问web应用时,服务端程序决定何时创建session,创建session可以概括为三个步骤:
1,生成全局唯一标识符(sessionid)
2,开辟数据存储空间。一般会在内存中创建相应的数据结构,但这种情况下,系统一旦掉电,所有的会话数据就会丢失,如果是电子商务网站,这种事故会造成严重的后果。不过也可以写到文件里甚至存储在数据库中,这样虽然会增加I/O开销,但session可以实现某种程度的持久化,而且更有利于session的共享;
3,将session的全局唯一标示符发送给客户端。
===
关于服务器如何将session的唯一标识发送个客户端,主要有两种方式:cookie和URL重写。Cookie与Session的区别中也有写到,这里不再详述。下面就开始说说PHP中的Session。
1,
session id 用户session唯一标识符,随机生成的一串字符串,具有唯一性,随机性。主要用于区分其它用户的session数据。用户第一次访问web页面的时候,php的session初始化函数调用会分配给当前来访用户一个唯一的ID,也称之为session_id。
2,
session data 我们把需要通过session保存的用户状态信息,称为用户session数据,也称为session数据。一般是在当前session生命周期,相应用的$_SESSION数据。
3,
session file PHP默认将session数据存放在一个文件里。我们把存放session数据的文件称为session文件。它由特殊的php.ini设置session.save_path指定session文件的存放路径,CentOS5.3操作系统,PHP5.1默认存放在/var/lib/php/session目录中。用户session文件的名称,就是以sess_为前缀,以session_id为结尾命名,比如session id为vp8lfqnskjvsiilcp1c4l484d3,那么session文件名就是sess_vp8lfqnskjvsiilcp1c4l484d3
4,
session lifetime 我们把初始化session开始,直到注销session这段期间,称为session生命周期,这样有助于我们理解session管理函数。
总结:由此,我们可见:当每个用户访问web, PHP的session初始化函数都会给当前来访用户分配一个唯一的session ID。并且在session生命周期结束的时候,将用户在此周期产生的session数据持久到session文件中。用户再次访问的时候,session初始化函数,又会从session文件中读取session数据,开始新的session生命周期。
===php.ini与session相关的设置:
1,
session.save_handler = file 用于读取/回写session数据的方式,默认是files。它会让PHP的session管理函数使用指定的文本文件存储session数据
2,
session.save_path = “/var/lib/php/session” 指定保存session文件的目录,可以指定到别的目录,但是指定目录必须要有httpd守护进程属主(比如apache或www等)写权限,否则无法回存session数据。当指定目录不存在时,php session环境初始化函数是不会帮你创建指定目录的,所以需要你手工建立指定目录。它还可以写成这样session.save_path = “N;/path” 其中N是整数。这样使得不是所有的session文件都保存在同一个目录中,而是分散在不同目录。这对于服务器处理大量session文件是很有帮助的。(注:目录需要自己手工创建)
3,
session.auto_start = 0 如果启用该选项,用户的每次请求都会初始化session。我们推荐不启用该设置,最好通过session_start()显示地初始化session
===========
session相关php函数和事件
1,
session_start()函数session_start会初始化session,也标示session声明周期的开始。要使用session,,必须初始化一个session环境。有点类似于OOP概念中调用构造函数构创建对象实例一样。session初始化操作,声明一个全局数组$_SESSION,映射寄存在内存的session数据。如果session文件已经存在,并且保存有session数据,session_start()则会读取session数据,填入$_SESSION中,开始一个新的session生命周期。
2,
$_SESSION 它是一个全局变量,类型是Array,映射了session生命周期的session数据,寄存在内存中。在session初始化的时候,从session文件中读取数据,填入该变量中。在session生命周期结束时,将$_SESSION数据写回session文件。
3,
session_register() 在session生命周期内,使用全局变量名称将注全局变量注册到当前session中。所谓注册,就是将变量填入$_SESSION中,值为NULL。它不会对session文件进行任何IO操作,只是影响$_SESSION变量。注意,它的正确写法是session_register(‘varname’),而不是session_register($varname)。
4,
session_unregister() 与session_register操作正好相反,即在session生命周期,从当前session注销指定变量。同样只影响$_SESSION,并不进行任何IO操作。
5,
session_unset() 在session生命周期,从当前session中注销全部session数据,让$_SESSION成为一个空数组。它与unset($_SESSION)的区别在于:unset直接删除$_SESSION变量,释放内存资源;另一个区别在于,session_unset()仅在session生命周期能够操作$_SESSION数组,而unset()则在整个页面(page)生命周期都能操作$_SESSION数组。session_unset()同样不进行任何IO操作,只影响$_SESSION数组。
6,
session_destroy() 如果说session_start()初始化一个session的话,而它则注销一个session。意味着session生命周期结束了。在session生命周期结整后,session_register, session_unset, session_register都将不能操作$_SESSION数组,而$_SESSION数组依然可以被unset()等函数操作。这时,session意味着是未定义的,而$_SESSION依然是一个全局变量,他们脱离了关映射关系。
7,
session_regenerate_id() 调用它,会给当前用户重新分配一个新的session id。并且在结束当前页面生命周期的时候,将当前session数据写入session文件。前提是,调用此函数之前,当前session生命周期没有被终止(参考第9点)。它会产生一个IO操作,创建一个新的session文件,创建新的session文件的是在session结束之前,而不是调用此函数就立即创建新的session文件。
8,
session_commit() session_commit()函数是session_write_close()函数的别名。它会结束当前session的生命周期,并且将session数据立即强制写入session文件。不推荐通过session_commit()来手工写入session数据,因为PHP会在页面生命周期结束的时候,自动结束当前没有终止的session生命周期。它会产生一个IO写操作。
9,
end session 结束session,默认是在页面生命周期结束的之前,PHP会自动结束当前没有终止的session。但是还可以通过session_commit()与session_destroy()二个函数提前结束session。不管是哪种方式,结束session都会产生IO操作,分别不一样。默认情况,产生一个IO写操作,将当前session数据写回session文件。session_commit()则是调用该函数那刻,产生一个IO写操作,将session数据写回session文件。而session_destroy()不一样在于,它不会将数据写回session文件,而是直接删除当前session文件。有趣的是,不管是session_commit(),还是session_destroy()都不会清空$_SESSION数组,更不会删除$_SESSION数组,只是所有session_*函数不能再操作session数据,因为当前的session生命周期终止了,即不能操作一个未定义对象。
================
==session ID是如何传递的?
session终究是因为管理用户状态信息才存在的。session id是用户表明身份的一种标识,就像入场券一样。用户一旦从被分配了session id之后的每次访问(http请求)都会携带这个session id给服务端,用于加载该用户的session数据。
用户端与服务端的web通信协议是http,而PHP通过http取得用户数据惯用的三种方法分别是:POST方法、GET方法还有Cookie。而PHP默认传递方法正是Cookie,也是最佳方法。只有在客户端不支持Cookie的时候(浏览器禁用了Cookie功能)才会通过GET方法来传递session_id,即通过在URL的query_string部分传递session id。
session id 的传递过程?用户通过浏览器访问页面,将url输入地址栏回车,浏览器发出请求,在调用socket send之前浏览器引擎会搜索有效的cookies记录封装在http请求头的cookie字段一同发送出去。服务端接收到请求后,交给php处理。这时,session初始化函数如果在$_COOKIE中没有找到以session_name()作为键值存储的元素(值为session_id),则会一位用户是第一次访问web。作为第一次访问的用户,session初始化函数总会随机生成一个session_id并且通过setcookie()函数调用新生成的session_id以“session_name = session_id”的格式填入http相应头set—cookie字段,发送给客户端(这样接下来的请求,http请求cookie字段都会携带该cookie记录为web服务器)。如果初始化函数发现用户端cookies中已定义了存在$_COOKIE['sess_name'],则会重新加载与$_COOKIE[‘sess_name’]相对应的session文件($_COOKIE[‘sess_name’]就是session ID)。如果用户Cookie记录过期,则会被浏览器删除。之后的下一次请求,服务器会以为用户又是第一次访问,如此循环。
================+》