深入理解PHP原理之Session Gc的一个小概率Notice


Posted in PHP onApril 12, 2011

如果在ubuntu/Debian下, 采用apt安装的PHP, 那么在使用Session的时候, 就可能会有小概率遇到这个提示.

PHP Notice: session_start(): ps_files_cleanup_dir: 
opendir(/var/lib/php5) failed: Permission denied (13) 
in /home/laruence/www/htdocs/index.php on line 22

这是因为, 在PHP中, 如果使用file_handler作为Session的save handler, 那么就有概率在每次session_start的时候运行Session的Gc过程.
//有省略 
int nrdels = -1; 
nrand = (int) ((float) PS(gc_divisor) * php_combined_lcg(TSRMLS_C)); 
if (nrand < PS(gc_probability)) { 
PS(mod)->s_gc(&PS(mod_data), PS(gc_maxlifetime), &nrdels TSRMLS_CC); 
} 
//有省略

这个警告的原因是因为在apt的PHP中, session的默认目录/var/lib/php5的权限是733 with sticky bit, 也就是
drwx-wx-wt root roo

而一般PHP的worker都运行在非root身份下, 所以是没有权限来打开这个文件夹的(但是因为可以write, 所以不影响正常的Session文件读取). 于是在s_gc中的如下代码, 就会触发开头所说的Notice:
//对于file handler来说, s_gc间接调用ps_files_cleanup_dir: 
dir = opendir(dirname); 
if (!dir) { 
php_error_docref(NULL TSRMLS_CC, E_NOTICE, 
"ps_files_cleanup_dir: opendir(%s) failed: %s (%d)", 
dirname, strerror(errno), errno); 
return (0); 
}

当然, 在ubuntu/Debian下, 还是有gc回收的, 只不过是外部的cron进程来完成的, 默认的在/etc/cron.d/php5:,
09,39 * * * * root [ -x /usr/lib/php5/maxlifetime ] 
&& [ -d /var/lib/php5 ] && find /var/lib/php5/ 
-type f -cmin +$(/usr/lib/php5/maxlifetime) -print0 
| xargs -n 200 -r -0 r

另外, 可以看到, 在判别s_gc是否运行的时候, 有俩个关键变量: PS(gc_divisor)和PS(gc_probability), 这俩个变量分别对应着session的运行时配置项的俩个同名配置项:
session.gc_probability和session.gc_divisor, 他们分别默认为1和100.
而php_combined_lcg是一个随机数发生器, 生成0到1范围的随机数, 所以上面的判别相当于:
rand < probability / gc_diviso

也就是说, 默认情况下, 差不多是100次能调用一次gc过程. 所以也就是小概率的可以看到这个Notice.
要关闭这个Notice, 只需要设置:
session.gc_probability = 0, 让s_gc完全没有运行的可能即可.
当然, 你也可以改变这个文件夹的权限…
最后, 感谢CFC4N提供这个问题.
作者: Laruence( )
本文地址: http://www.laruence.com/2011/03/29/1949.html
PHP 相关文章推荐
用libTemplate实现静态网页的生成
Oct 09 PHP
网站加速 PHP 缓冲的免费实现方法
Oct 09 PHP
php xml留言板 xml存储数据的简单例子
Aug 24 PHP
有关JSON以及JSON在PHP中的应用
Apr 09 PHP
PHP开发者常犯的10个MySQL错误更正剖析
Jan 30 PHP
php自定义hash函数实例
May 05 PHP
求帮忙修改个php curl模拟post请求内容后并下载文件的解决思路
Sep 20 PHP
php视频拍照上传头像功能实现代码分享
Oct 08 PHP
PHP多维数组遍历方法(2种实现方法)
Dec 10 PHP
PHP基于curl后台远程登录正方教务系统的方法
Oct 14 PHP
Yii2框架实现数据库常用操作总结
Feb 08 PHP
cakephp常见知识点汇总
Feb 24 PHP
php表单提交问题的解决方法
Apr 12 #PHP
使用NetBeans + Xdebug调试PHP程序的方法
Apr 12 #PHP
php产生随机数的两种方法实例代码 输出随机IP
Apr 08 #PHP
PHP随机数生成代码与使用实例分析
Apr 08 #PHP
PHP的cURL库功能简介 抓取网页、POST数据及其他
Apr 07 #PHP
php curl 登录163邮箱并抓取邮箱好友列表的代码(经测试)
Apr 07 #PHP
The specified CGI application misbehaved by not returning a complete set of HTTP headers
Mar 31 #PHP
You might like
php三维数组去重(示例代码)
2013/11/26 PHP
ThinkPHP结合ajax、Mysql实现的客户端通信功能代码示例
2014/06/23 PHP
php计算两个整数的最大公约数常用算法小结
2015/03/05 PHP
在WordPress中使用PHP脚本来判断访客来自什么国家
2015/12/10 PHP
CSDN轮换广告图片轮换效果
2007/03/27 Javascript
Javascript 生成指定范围数值随机数
2009/01/09 Javascript
广告切换效果(缓动切换)
2009/05/27 Javascript
javascript 实现键盘上下左右功能的小例子
2013/09/15 Javascript
JS控制一个DIV层在指定时间内消失的方法
2014/02/17 Javascript
javascript中的正则表达式使用指南
2015/03/01 Javascript
HTML5使用DeviceOrientation实现摇一摇功能
2015/06/05 Javascript
JavaScript使用encodeURI()和decodeURI()获取字符串值的方法
2015/08/04 Javascript
jQuery+CSS3+Html5实现弹出层效果实例代码(附源码下载)
2016/05/16 Javascript
jquery插件方式实现table查询功能的简单实例
2016/06/06 Javascript
jQuery插件jqGrid动态获取列和列字段的方法
2017/03/03 Javascript
vue实现一个炫酷的日历组件
2018/10/08 Javascript
vue+Element中table表格实现可编辑(select下拉框)
2020/05/21 Javascript
python3实现ftp服务功能(客户端)
2017/03/24 Python
django将图片上传数据库后在前端显式的方法
2018/05/25 Python
python中csv文件的若干读写方法小结
2018/07/04 Python
Python 类属性与实例属性,类对象与实例对象用法分析
2019/09/20 Python
python科学计算之numpy——ufunc函数用法
2019/11/25 Python
使用 Python 写一个简易的抽奖程序
2019/12/08 Python
如何在python中执行另一个py文件
2020/04/30 Python
如何使用Pytorch搭建模型
2020/10/26 Python
html5实现微信打飞机游戏
2014/03/27 HTML / CSS
三星美国官网:Samsung美国
2017/02/06 全球购物
真正的英国宝藏:Mappin & Webb
2019/05/05 全球购物
Nanushka官网:匈牙利服装品牌
2019/08/14 全球购物
系统管理员的职责包括那些?管理的对象是什么?
2016/09/20 面试题
买卖合同协议书范本
2014/10/18 职场文书
综治维稳工作汇报
2014/10/27 职场文书
思想品德评语大全
2014/12/31 职场文书
计划生育目标责任书
2015/05/09 职场文书
2016中秋晚会开幕词
2016/03/03 职场文书
三十年再续同学情倡议书
2019/11/27 职场文书