深入理解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 相关文章推荐
php 获取完整url地址
Dec 20 PHP
php设计模式 Composite (组合模式)
Jun 26 PHP
ubuntu10.04配置 nginx+php-fpm模式的详解
Jun 03 PHP
PHP生成Gif图片验证码
Oct 27 PHP
PHP实现格式化文件数据大小显示的方法
Jan 03 PHP
PHP结合jQuery.autocomplete插件实现输入自动完成提示的功能
Apr 27 PHP
PHP获取Exif缩略图的方法
Jul 13 PHP
微信支付开发告警通知实例
Jul 12 PHP
php中的异常和错误浅析
May 03 PHP
PHP那些琐碎的知识点(整理)
May 20 PHP
PHP实现可精确验证身份证号码的工具类示例
May 31 PHP
因str_replace导致的注入问题总结
Aug 08 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或asp创建网页桌面快捷方式的代码
2010/03/23 PHP
php addslashes及其他清除空格的方法是不安全的
2012/01/25 PHP
php合并js请求的例子
2013/11/01 PHP
JavaScript 学习笔记(四)
2009/12/31 Javascript
JavaScript 学习笔记(五)
2009/12/31 Javascript
JavaScript计算某一天是星期几的方法
2015/08/05 Javascript
详解Javacript和AngularJS中的Promises
2016/02/09 Javascript
基于javascript实现全屏漂浮广告
2016/03/31 Javascript
JavaScript跨域调用基于JSON的RESTful API
2016/07/09 Javascript
jquery遍历标签中自定义的属性方法
2016/09/17 Javascript
js获取时间函数及扩展函数的方法
2016/10/30 Javascript
Bootstrap 模态框多次显示后台提交多次BUG的解决方法
2017/12/26 Javascript
JavaScript实现动态添加、移除元素或属性的方法分析
2019/01/03 Javascript
JS实现json数组排序操作实例分析
2019/10/28 Javascript
vue keep-alive列表页缓存 详情页返回上一页不刷新,定位到之前位置
2019/11/26 Javascript
基于JS实现计算24点算法代码实例解析
2020/07/23 Javascript
vant中的toast层级改变操作
2020/11/04 Javascript
python使用Tkinter实现在线音乐播放器
2018/01/30 Python
Python使用cx_Oracle模块操作Oracle数据库详解
2018/05/07 Python
解决python写入带有中文的字符到文件错误的问题
2019/01/31 Python
python在回调函数中获取返回值的方法
2019/02/22 Python
详解小白之KMP算法及python实现
2019/04/04 Python
将pymysql获取到的数据类型是tuple转化为pandas方式
2020/05/15 Python
keras中的loss、optimizer、metrics用法
2020/06/15 Python
深入了解Python enumerate和zip
2020/07/16 Python
python通过函数名调用函数的几种场景
2020/09/23 Python
python 利用matplotlib在3D空间绘制二次抛物面的案例
2021/02/06 Python
CSS3教程(4):网页边框和网页文字阴影
2009/04/02 HTML / CSS
好药师网上药店:安全合法的网上药品零售药房
2017/02/15 全球购物
你对IPv6了解程度
2016/02/09 面试题
开门红主持词
2014/04/02 职场文书
《彭德怀和他的大黑骡子》教学反思
2014/04/12 职场文书
企业安全生产承诺书
2014/05/22 职场文书
大学生标准自荐书
2014/06/15 职场文书
教师考核评语大全
2014/12/31 职场文书
博士论文答辩开场白
2015/06/01 职场文书