php session原理
session是在服务器端保持用户会话数据的一种方法,对应的cookie是在客户端保持用户数据。http协议是一种无状态协议,服务器响应完后就失去了与浏览器的联系,cookie引入浏览器,使得数据跨越页面交换。
首先客户端和服务器端建立一一联系,每个客户端都有一个唯一标识,这样服务器才能识别出来。建议唯一标识的方法有两种:cookie或者通过get方式指定。默认配置的php使用session的时会建立一个名叫”phpsessid”的cookie(可以通过php.ini修改session.name值指定),如果客户端禁用cookie,你也可以指定通过get方式把session id传到服务器(修改php.ini中session.use_trans_sid等参数)。
客户端将session id传递到服务器,服务器根据session id找到对应的文件,读取的时候对文件内容进行反序列化就得到session的值,保存的时候先序列化再写入。
事实就是这样,如果服务器不支持session或者你想自定义session,完全可以diy,通过php的uniqid生成永不重复的session id,然后找个地方存储session的内容即可,还可以把session存储在mysql数据库中。
所谓的session其实就是客户端一个session id,服务器端一个session file,新建session时,告诉服务器要生成一个cookie以及准备好session文件,要不然你的session内容怎么存;读取session时告诉服务器,赶紧根据session id把session文件反序列化。
session影响系统性能
session在大访问量网站上确实影响系统性能,影响性能的原因之一由文件系统设计造成,在同一个目录下超过10000个文件时,文件的定位将非常耗时,php支持session目录hash,我们可以通过修改php.ini中session.save_path =“2;/path/to/session/dir”,那么session将存储在两级子目录中,每个目录有16个子目录[0~f],不过好像phpsession不支持创建目录,你需要事先把那么些目录创建好 。
还有一个问题就是小文件的效率问题,一般我们的session数据都不会太大(1~2k),如果有大量这样1~2k的文件在磁盘上,io效率肯定会很差。可以通过缓存memcache和mysql数据库提供效率。
session的同步
前端可能有很多台服务器,用户在a服务器上登录了,种下了session信息,然后访问网站的某些页面没准跳到b服务器上去了,如果这个时候b服务器上没有session信息又没有做特殊处理,可能就会出问题了。
session同步有很多种,如果你是存储在memcached或者mysql中,那就很容易了,指定到同样的位置即可,如果是文件形式的,你可以用nfs统一存储。
(nfs是network file system的简写,即网络文件系统.网络文件系统是freebsd支持的文件系统中的一种,也被称为nfs. nfs允许一个系统在网络上与他人共享目录和文件。通过使用nfs,用户和程序可以像访问本地文件一样访问远端系统上的文件。)
还有一种方式是通过加密的cookie来实现,用户在a服务器上登录成功,在用户的浏览器上种上一个加密的cookie,当用户访问b服务器时,检查有无session,如果有当然没问题,如果没有,就去检验cookie是否有效,cookie有效的话就在b服务器上重建session。这种方法其实很有用,如果网站有很多个子频道,服务器也不在一个机房,session没办法同步又想做统一登录那就太有用了。
当然还有一种方法就是在负载均衡那一层保持会话,把访问者绑定在某个服务器上,他的所有访问都在那个服务器上就不需要session同步了。
;
第一次请求服务器:
get/test.php http/1.1
accept:*/*
referer:http://localhost/
accept-language:zh-cn
accept-encoding:gzip, deflate
user-agent: mozilla/4.0 (compatible; msie6.0; windows nt 5.1; sv1; maxthon; .net clr 1.1.4322)
host:localhost
connection:keep-alive
服务器第一次返回:
http/1.1200 ok
date:fri, 26 aug 2005 07:44:22 gmt
server:apache/2.0.54 (win32) svn/1.2.1 php/5.0.4 dav/2
x-powered-by:php/5.0.4
set-cookie:phpsessid=bmmc3mfc94ncdr15ujitjogma3; path=/
expires:thu, 19 nov 1981 08:52:00 gmt
cache-control: no-store, no-cache,must-revalidate, post-check=0, pre-check=0
pragma:no-cache
content-length:1
keep-alive:timeout=15, max=99
connection:keep-alive
content-type:text/html; charset=utf-8
content-language:off
第二次请求服务器:
get/test.php http/1.1
accept:*/*
referer:http://localhost/
accept-language:zh-cn
accept-encoding:gzip, deflate
user-agent: mozilla/4.0 (compatible; msie6.0; windows nt 5.1; sv1; maxthon; .net clr 1.1.4322)
host:localhost
connection:keep-alive
cookie: phpsessid=bmmc3mfc94ncdr15ujitjogma3
服务器第二次返回:
http/1.1200 ok
date:fri, 26 aug 2005 07:44:23 gmt
server:apache/2.0.54 (win32) svn/1.2.1 php/5.0.4 dav/2
x-powered-by:php/5.0.4
set-cookie:phpsessid=bmmc3mfc94ncdr15ujitjogma3; path=/
expires:thu, 19 nov 1981 08:52:00 gmt
cache-control: no-store, no-cache,must-revalidate, post-check=0, pre-check=0
pragma:no-cache
content-length:1
keep-alive:timeout=15, max=98
connection:keep-alive
content-type:text/html; charset=utf-8
content-language:off
仔细对比这些输出,第二次请求比第一次请求多出来的就是:
cookie:phpsessid=bmmc3mfc94ncdr15ujitjogma3
这个header将会向服务器发送一个cookie信息,告诉服务器我有一个cookie,名字叫phpsessid,内容是bmmc3mfc94ncdr15ujitjogma3。
这个cookie是怎么来的呢?看第一次服务器返回的信息里边有:
set-cookie:phpsessid=bmmc3mfc94ncdr15ujitjogma3; path=/
这是服务器向客户端浏览器写一个cookie,名字是phpsessid,值是bmmc3mfc94ncdr15ujitjogma3,这个值实际就是所谓的session_id。
继续看第二次向服务器发出的请求,仍然向服务器发送了phpsessid这个cookie
可以得到以下结论:
1、只要使用了session,就会通过cookie的方式向客户端浏览器发送session
2、每次向服务器发出请求的时候,本地浏览器会把cookie附带在请求信息中
cookie
cookie 是一种在远程浏览器端储存数据并以此来跟踪和识别用户的机制。
php在http 协议的头信息里发送cookie,因此setcookie()函数必须在其它信息被输出到浏览器前调用。
原理.
a.服务器通过随着响应发送一个http 的set-cookie 头,在客户机中设置一个cookie(多个cookie 要多个头)。
b.客户端自动向服务器端发送一个http 的cookie 头,服务器接收读取。
http/1.x 200 ok
x-powered-by: php/5.2.1
set-cookie:testcookie=something from somewhere; path=/
expires: thu, 19 nov 2007 18:52:00 gmt
cache-control: no-store, no-cache,must-revalidate, post-check=0,pre-check=0
pragma: no-cache
content-type: text/html
这一行实现了cookie 功能,收到这行后
set-cookie: testcookie=something fromsomewhere; path=/
浏览器将在客户端的磁盘上创建一个cookie 文件。
下面的同样的效果:
setcookie('testcookie','something from somewhere','/');
header('set-cookie:testcookie=something from somewhere; path=/')
常见问题解决:
1) 用 setcookie()时有错误提示,可能是因为调用setcookie()前面有输出或空格。
2) $_cookie 受magic_quotes_gpc 影响,可能自动转义。
3) 使用的时候,有必要测试用户是否支持cookie。
下面以用户登录为例分析session和cookie
http协议是一种无状态协议,服务器响应完用户的请求,就失去了与浏览器的联系,php是如何实现session的。
用户第一次访问服务器时,因为没有session信息,需要登录验证,用户通过表单把用户名,密码,验证码等信息提交给服务器,服务器在验证用户的合法性之前先对数据进行预处理。通过到数据库验证,用户是合法的,这个时候服务器会给浏览器信息中包含set-cookie: phpsessid=bmmc3mfc94ncdr15ujitjogma3;这样的信息,这样浏览器会把信息写到本地文件中,其中phpsessid为唯一标识符。同时服务器也会在指定的文件把序列化的session信息保存在文件中。当用户再次请求时,浏览器会把对应cookie中的phpsessid也发送给服务器,服务器得到phpsessid,会到session文件中验证,如果验证成功,就直接登录。从而类似的可以实现数据在不同用户页面之前的传递。session中的值是key-value。
session影响系统性能
session在大访问量网站上确实影响系统性能,影响性能的原因之一由文件系统设计造成,在同一个目录下超过10000个文件时,文件的定位将非常耗时,php支持session目录hash,我们可以通过修改php.ini中session.save_path =“2;/path/to/session/dir”,那么session将存储在两级子目录中,每个目录有16个子目录[0~f],不过好像phpsession不支持创建目录,你需要事先把那么些目录创建好 。
还有一个问题就是小文件的效率问题,一般我们的session数据都不会太大(1~2k),如果有大量这样1~2k的文件在磁盘上,io效率肯定会很差。可以通过缓存memcache和mysql数据库提供效率。
session的同步
前端可能有很多台服务器,用户在a服务器上登录了,种下了session信息,然后访问网站的某些页面没准跳到b服务器上去了,如果这个时候b服务器上没有session信息又没有做特殊处理,可能就会出问题了。
session同步有很多种,如果你是存储在memcached或者mysql中,那就很容易了,指定到同样的位置即可,如果是文件形式的,你可以用nfs统一存储。
(nfs是network file system的简写,即网络文件系统.网络文件系统是freebsd支持的文件系统中的一种,也被称为nfs. nfs允许一个系统在网络上与他人共享目录和文件。通过使用nfs,用户和程序可以像访问本地文件一样访问远端系统上的文件。)
还有一种方式是通过加密的cookie来实现,用户在a服务器上登录成功,在用户的浏览器上种上一个加密的cookie,当用户访问b服务器时,检查有无session,如果有当然没问题,如果没有,就去检验cookie是否有效,cookie有效的话就在b服务器上重建session。这种方法其实很有用,如果网站有很多个子频道,服务器也不在一个机房,session没办法同步又想做统一登录那就太有用了。
还有一种方法就是在负载均衡那一层保持会话,把访问者绑定在某个服务器上,其他所有访问都在那个服务器上就不需要
http://www.bkjia.com/phpjc/477521.htmlwww.bkjia.comtruehttp://www.bkjia.com/phpjc/477521.htmltecharticlephp session原理 session是在服务器端保持用户会话数据的一种方法,对应的cookie是在客户端保持用户数据。http协议是一种无状态协议,服务器...