深入理解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的图形函数中显示汉字
Oct 09 PHP
并发下常见的加锁及锁的PHP具体实现代码
Oct 12 PHP
PHP递归算法的详细示例分析
Feb 19 PHP
解析关于java,php以及html的所有文件编码与乱码的处理方法汇总
Jun 24 PHP
PHP按行读取、处理较大CSV文件的代码实例
Apr 09 PHP
PHP实现通过中文字符比率来判断垃圾评论的方法
Oct 20 PHP
前端必学之PHP语法基础
Jan 01 PHP
php魔法函数与魔法常量使用介绍
Jul 23 PHP
php+ajax实现无刷新文件上传功能(ajaxuploadfile)
Feb 11 PHP
PHP中通过getopt解析GNU C风格命令行选项
Nov 18 PHP
php操作redis数据库常见方法实例总结
Feb 20 PHP
PHP如何获取Cookie并实现模拟登录
Jul 16 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/02/03 PHP
PHP四大安全策略
2014/03/12 PHP
PHP中防止SQL注入方法详解
2014/12/25 PHP
织梦sitemap地图实时推送给百度的教程
2015/08/03 PHP
php获取客户端IP及URL的方法示例
2017/02/03 PHP
yii2.0整合阿里云oss删除单个文件的方法
2017/09/19 PHP
精心挑选的15个jQuery下拉菜单制作教程
2012/06/15 Javascript
js判断生效时间不得大于失效时间的思路及代码
2013/04/23 Javascript
js操作iframe兼容各种主流浏览器示例代码
2013/07/22 Javascript
简单的代码实现jquery定时器
2014/01/03 Javascript
jQuery中:only-child选择器用法实例
2015/01/03 Javascript
bootstrap布局中input输入框右侧图标点击功能
2016/05/16 Javascript
浅谈vue,angular,react数据双向绑定原理分析
2017/11/28 Javascript
jquery使用FormData实现异步上传文件
2018/10/25 jQuery
JQuery animate动画应用示例
2019/05/14 jQuery
编写v-for循环的技巧汇总
2020/12/01 Javascript
Python高效编程技巧
2013/01/07 Python
sublime text 3配置使用python操作方法
2017/06/11 Python
python+opencv轮廓检测代码解析
2018/01/05 Python
详解python中@的用法
2019/03/27 Python
对Python中class和instance以及self的用法详解
2019/06/26 Python
pandas DataFrame行或列的删除方法的实现示例
2019/08/02 Python
浅谈keras中自定义二分类任务评价指标metrics的方法以及代码
2020/06/11 Python
keras得到每层的系数方式
2020/06/15 Python
Python子进程subpocess原理及用法解析
2020/07/16 Python
python 下载文件的多种方法汇总
2020/11/17 Python
HTML5如何为形状图上颜色怎么绘制具有颜色和透明度的矩形
2014/06/23 HTML / CSS
日本动漫周边服饰销售网站:Atsuko
2019/12/16 全球购物
SAZAC的动物连体衣和动物睡衣:Kigurumi Shop
2020/03/14 全球购物
IMPORT的选项IGNORE有什么作用?缺省是什么设置?
2015/09/17 面试题
酒店管理毕业生自荐信
2014/05/25 职场文书
安全环保演讲稿
2014/08/28 职场文书
县委常委班子对照检查材料思想汇报
2014/09/28 职场文书
2014年乡镇人大工作总结
2014/11/25 职场文书
客户经理岗位职责
2015/01/31 职场文书
2019年中,最受大众欢迎的6本新书
2019/08/07 职场文书