深入理解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获得文件扩展名三法
Nov 25 PHP
计算一段日期内的周末天数的php代码(星期六,星期日总和)
Nov 12 PHP
Thinkphp模板中使用自定义函数的方法
Sep 23 PHP
php中get_object_vars()方法用法实例
Feb 08 PHP
Zend Framework教程之配置文件application.ini解析
Mar 10 PHP
解析PHP的Yii框架中cookie和session功能的相关操作
Mar 17 PHP
PHP简单实现DES加密解密的方法
Jul 12 PHP
Yii调试查看执行SQL语句的方法
Jul 15 PHP
thinkPHP中钩子的使用方法实例分析
Nov 16 PHP
PHP+RabbitMQ实现消息队列的完整代码
Mar 20 PHP
PHP+fiddler抓包采集微信文章阅读数点赞数的思路详解
Dec 20 PHP
PHP基于phpqrcode类生成二维码的方法示例详解
Aug 07 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
CI框架装载器Loader.php源码分析
2014/11/04 PHP
php实现webservice实例
2014/11/06 PHP
thinkphp文件处理类Dir.class.php的用法分析
2014/12/08 PHP
javascript真的不难-回顾一下基础知识
2013/01/15 Javascript
Javascript 多浏览器兼容总结(实战经验)
2013/10/30 Javascript
jquery动态加载select下拉框示例代码
2013/12/10 Javascript
js 实现的可折叠留言板(附源码下载)
2014/07/01 Javascript
javascript数组去重的方法汇总
2015/04/14 Javascript
在Javascript中处理数组之toSource()方法的使用
2015/06/09 Javascript
JS实现先显示大图后自动收起显示小图的广告代码
2015/09/04 Javascript
JS实现随机颜色的3种方法与颜色格式的转化
2017/01/05 Javascript
vue.js开发环境安装教程
2017/03/17 Javascript
Angular中ng-bind和ng-model的区别实例详解
2017/04/10 Javascript
微信小程序之滚动视图容器的实现方法
2017/09/26 Javascript
vue-cli webpack2项目打包优化分享
2018/02/07 Javascript
element ui 对话框el-dialog关闭事件详解
2018/02/26 Javascript
小程序实现单选多选功能
2018/11/04 Javascript
微信小程序textarea层级过高(盖住其他元素)问题的解决办法
2019/03/04 Javascript
详解关于表格合并span-method方法的补充(表格数据由后台动态返回)
2019/05/21 Javascript
js实现从右往左匀速显示图片(无缝轮播)
2020/06/29 Javascript
python3访问sina首页中文的处理方法
2014/02/24 Python
python使用心得之获得github代码库列表
2014/06/25 Python
python实现汽车管理系统
2018/11/30 Python
python使用paramiko模块通过ssh2协议对交换机进行配置的方法
2019/07/25 Python
python正则过滤字母、中文、数字及特殊字符方法详解
2020/02/11 Python
基于python实现简单C/S模式代码实例
2020/09/14 Python
CSS3实现图片抽屉式效果的示例代码
2019/11/06 HTML / CSS
龟牌英国商店:Turtle Wax Brand Store UK
2019/07/02 全球购物
印度在线购买电子产品网站:Croma
2020/01/02 全球购物
毕业生大学生活自我总结
2014/01/31 职场文书
高中军训感言600字
2014/03/11 职场文书
留学顾问岗位职责
2014/04/14 职场文书
中职毕业生自我鉴定
2014/09/13 职场文书
2015年护士节活动总结
2015/02/10 职场文书
详解Node.js如何处理ES6模块
2021/05/15 Javascript
Django+Nginx+uWSGI 定时任务的实现方法
2022/01/22 Python