2.1 Session在PHP中的使用
PHP Session使得LAMP架构式的网站中各页面之间的数据交换成为可能。每一个访问网站的用户在第一次访问网站时均会被分配到一个唯一ID,即session id,则在接下来的再次访问网站时则只需要携带上session id,网站服务器端即可通过它识别当前访问的用户,而具体的session数据部分则存储在服务器上(基于session id区别各独立访客)。大致流程如下图所示(session id的传递采用存储在cookie中的方式)。
Session模块
Session作为PHP的扩展模块而存在,目前已嵌入PHP内核之中,故默认是激活状态。*nix下通过php -m命令行即可查看到当前PHP解释器启用的模块:
可通过修改php.ini文件中的session配置来更改session模块的默认行为,其主要配置选项如下:
1、存储设置
- session.save_handler:定义了session信息的存储类型,默认为文件(session.save_handler = files),PHP默认情况下以文件形式存储sesion信息。
- session.save_path:定义了session数据的存储访问路径,根据save_handler的选择而所有不同,如存储类型为文件,则此处文件路径(session.save_path = "/tmp");如存储类型修改为数据库或Redis,则其值为数据库或Redis的有效访问连接(如session.save_path = "tcp://localhost:6379")。
2、Session-Cookie设置
- session.use_cookies:指定是否在通过设置cookie来实现session id的传递(存储)。默认为1(启用)。有两种方式实现客户端与服务器之间的session id的传递:保存在cookie中和以参数形式附加在请求url中。后者安全性较低,通常采用前者。
- session.use_only_cookies:指定是否仅仅通过客户端的cookie来存储session id,自PHP 5.3.0起默认为1(启动)。这个选项主要是防止来自通过url传递session id的攻击。
- session.cookie_lifetime:表示发送至浏览器客户端的cookie的生存期,单位秒。默认为0,表示:直到浏览器关闭。
- session.cookie_path:表示发送至浏览器客户端的cookie的访问路径。默认为"/",表示:网站根目录。
- session.cookie_domain:表示发送至浏览器客户端的cookie的访问域名。默认为空,表示:当前生成cookie的主机名。 - session.cookie_secure:表示是否要求客户端通过安全连接(HTTPS)发送cookie。默认为空,即不启用。
- session.cookie_httponly:指定cookie是否仅仅通过HTTP协议访问。这意味着一些客户端脚本语言如JavaScript则无权访问服务器端设置的cookie,这有效地减少了XSS的身份篡改(并非所有浏览器均支持)
3、名称设置
- session.name,:指定session信息的名称,用于在客户端cookie中表示来自服务器的session id的key。
默认设置为:session.name = PHPSESSID,而session id的value为cookie中PHPSESSION key对应的键值,如以下为某一PHP网站中的cookie:
4、启动方式设置
- session.auto_start:表示session模块是否在客户端请求开始时自动开启一个会话,其值默认为零,即表示:默认不启动。
5、过期时间设置
php中的session模块为每个请求定义了一个的有效期概念,超过有效期之后,则会由php内核启动GC(garbage collection 垃圾回收)机制将请求中的session信息清除(在session_start()函数执行期间执行)。
- session.gc_probability:表示启动GC进程的概率之分子,默认为1。
- session.gc_divisor:表示启动GC进程的概率之分母,默认为100。gc_probability与gc_divisor选项配置使用(gc_probability/gc_divisor),共同决定了启动GC机制的概率,如1/100表示每个请求会话中有1%的概率启动GC。
- session.gc_maxlifetime:设置session过期时间的另外一种方法,它指定每个请求的session信息最大生存时间,单位为秒。超过设置的秒数之后,session信息将被标记为『垃圾』,然后交由GC进程清理(前提是:GC进程在会话开始时已启动 - 满足了启动概率)。默认值为1440s,即24分钟。
注:如果session存储方式采用的是默认的文件存储,则最终session变量是否被真正清除掉还依赖于服务器系统是否支持记录访问时间(access times, atime)的功能,否则仍无法清理。如Windows FAT格式的文件系统就不支持,好在自PHP4.2.3之后,使用modified times代替access times作为文件更新的依据。此外,当session文件被删掉时,对应内存中的$_SESSION变量没有来得及更新,则也视为有效,其实已经无效了。
考虑到以上种种不确定性因素,通常建议自行实现session过期时间的机制。使用一个表示最近活跃时间的时戳key即可达到目的,然后在每次请求时更新该key值。示例代码如下:
session使用
在PHP中使用session是非常简单的,它提供了一个全局变量($_SESSION)来便捷地操作当前请求的session信息。
1、启动一个session
在php中,通过执行session_start()函数可以手动开始一个会话(session)。如前所述,php.ini中的session.auto_start = 1,则服务器在接收到客户端的请求时会自动启动一个会话。
当服务器端启动一个会话时:
- php脚本首先会创建一个32位长度的十六进制随机串,即作为PHPSESSID的值。
- 然后通过HTTP协议的Set-Cookie头部将PHPSESSID的key/value发送给客户端。
- 最后根据php.ini中的配置项在指定位置(如临时目录)创建唯一的session信息文件(名称形如sess ie sess*)。
2、读/写一个session变量
session的表现形式本质上是一种数据结构,为存取session信息更加方便,php定义了$_SESSION全局变量来存储当前请求的会话信息,$_SESSION是一种关联数组的数据结构,key是字符串,value为对象。当前用户读写会话信息均可以通过操作此变量来实现(而不是『笨重』的去读/写session文件)。
3、清除一个session变量
php中使用unset函数即可清除一个session变量,如:unset($_SESSION['views'])。
当退出当前会话时需要清除所有设置的session变量时,可使用session_destroy()函数。
References
1、http://php.net/manual/en/intro.session.php
1、http://php.net/manual/zh/session.installation.php
2、https://www.tutorialspoint.com/php/php_sessions.htm
3、http://php.net/manual/zh/session.configuration.php#ini.session.auto-start
4、http://www.asifblog.com/2012/05/how-session-works-in-web-applications.html
5、http://stackoverflow.com/questions/520237/how-do-i-expire-a-php-session-after-30-minutes
6、http://php.net/manual/en/session.configuration.php#ini.session.gc-maxlifetime