深入理解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初学者头疼问题总结
Jul 08 PHP
基于mysql的论坛(2)
Oct 09 PHP
解析PHP中常见的mongodb查询操作
Jun 20 PHP
解析将多维数组转换为支持curl提交的一维数组格式
Jul 08 PHP
PHP使用CURL实现对带有验证码的网站进行模拟登录的方法
Jul 23 PHP
php通过隐藏表单控件获取到前两个页面的url
Sep 09 PHP
PHP中变量引用与变量销毁机制分析
Nov 15 PHP
PHP中创建图像并绘制文字的例子
Nov 19 PHP
thinkphp连贯操作实例分析
Nov 22 PHP
PHP如何实现Unicode和Utf-8编码相互转换
Jul 29 PHP
Yii2实现ActiveForm ajax提交
May 26 PHP
php在windows环境下获得cpu内存实时使用率(推荐)
Feb 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
一个简单计数器的源代码
2006/10/09 PHP
php ob_flush,flush在ie中缓冲无效的解决方法
2010/05/09 PHP
php 中的4种标记风格介绍
2012/05/10 PHP
PHP实现对站点内容外部链接的过滤方法
2014/09/10 PHP
php用户注册信息验证正则表达式
2015/11/12 PHP
php获取文件后缀的9种方法
2016/03/22 PHP
Laravel实现autoload方法详解
2017/05/07 PHP
jQuery EasyUI API 中文文档 - ComboTree组合树
2011/10/11 Javascript
NodeJS 模块开发及发布详解分享
2012/03/07 NodeJs
jQuery常用操作方法及常用函数总结
2014/06/19 Javascript
AngularJS基础 ng-dblclick 指令用法
2016/08/01 Javascript
浅谈js中字符和数组一些基本算法题
2016/08/15 Javascript
AngularJS  $modal弹出框实例代码
2016/08/24 Javascript
js通过指定下标或指定元素进行删除数组的实例
2017/01/12 Javascript
用Node编写RESTful API接口的示例代码
2018/07/04 Javascript
详解Nuxt内导航栏的两种实现方式
2020/04/16 Javascript
vue中el-input绑定键盘按键(按键修饰符)
2020/07/22 Javascript
vue双击事件2.0事件监听(点击-双击-鼠标事件)和事件修饰符操作
2020/07/27 Javascript
浅谈vue在html中出现{{}}的原因及解决方式
2020/11/16 Javascript
python实现图书管理系统
2018/03/12 Python
Python实现全排列的打印
2018/08/18 Python
一个可以套路别人的python小程序实例代码
2019/04/09 Python
python3 pygame实现接小球游戏
2019/05/14 Python
python 直接赋值和copy的区别详解
2019/08/07 Python
Python嵌套函数,作用域与偏函数用法实例分析
2019/12/26 Python
Win10用vscode打开anaconda环境中的python出错问题的解决
2020/05/25 Python
CSS3 Media Queries(响应式布局可以让你定制不同的分辨率和设备)
2013/06/06 HTML / CSS
一篇文章带你学习CSS3图片边框
2020/11/04 HTML / CSS
html5定制表单_动力节点Java学院整理
2017/07/11 HTML / CSS
迪卡侬印尼体育用品商店:Decathlon印尼
2020/03/11 全球购物
商场总经理岗位职责
2014/02/03 职场文书
后勤服务中心总经理工作职责
2014/03/03 职场文书
暑假安全教育广播稿
2014/09/10 职场文书
2014年大学生党员自我评议
2014/09/22 职场文书
热血教师观后感
2015/06/10 职场文书
2016年共产党员公开承诺书
2016/03/24 职场文书