深入理解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实现用户认证及管理完全源码
Mar 11 PHP
php+AJAX传送中文会导致乱码的问题的解决方法
Sep 08 PHP
PHP开发中四种查询返回结果分析
Jan 02 PHP
php线性表顺序存储实现代码(增删查改)
Feb 16 PHP
php异常处理技术,顶级异常处理器
Jun 13 PHP
PHP数组循环操作详细介绍 附实例代码
Feb 03 PHP
浅谈apache和nginx的rewrite的区别
Feb 22 PHP
解析php file_exists无效的解决办法
Jun 26 PHP
PHP生成压缩文件实例
Feb 07 PHP
在Linux系统下一键重新安装WordPress的脚本示例
Jun 30 PHP
PHP解压tar.gz格式文件的方法
Feb 14 PHP
关于 Laravel Redis 多个进程同时取队列问题详解
Dec 25 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 魔术方法使用说明
2009/10/20 PHP
php商品对比功能代码分享
2015/09/24 PHP
PHP使用PDO操作数据库的乱码问题解决方法
2016/04/08 PHP
win10环境PHP 7 安装配置【教程】
2016/05/09 PHP
阻止JavaScript事件冒泡传递(cancelBubble 、stopPropagation)
2007/05/08 Javascript
两个比较有用的Javascript工具函数代码
2010/02/17 Javascript
jquery插件开发方法(初学者)
2012/02/03 Javascript
javascript显示用户停留时间的简单实例
2013/08/05 Javascript
jquery实现点击文字可编辑并修改保存至数据库
2014/04/15 Javascript
用js格式化金额可设置保留的小数位数
2014/05/09 Javascript
jQuery实现tab选项卡效果的方法
2015/07/08 Javascript
javascript实现别踩白块儿小游戏程序
2015/11/22 Javascript
Vue.js父与子组件之间传参示例
2017/02/28 Javascript
js中this的指向问题归纳总结
2018/11/28 Javascript
详解vue-cli 脚手架 安装
2019/04/16 Javascript
微信小程序实现圆形进度条动画
2020/11/18 Javascript
js常用方法、检查是否有特殊字符串、倒序截取字符串操作完整示例
2020/01/26 Javascript
JS错误处理与调试操作实例分析
2020/04/13 Javascript
微信小程序选择图片控件
2021/01/19 Javascript
解决python3中解压zip文件是文件名乱码的问题
2018/03/22 Python
删除python pandas.DataFrame 的多重index实例
2018/06/08 Python
Python爬取数据并写入MySQL数据库的实例
2018/06/21 Python
pandas.dataframe按行索引表达式选取方法
2018/10/30 Python
Django之使用内置函数和celery发邮件的方法示例
2019/09/16 Python
python如何设置静态变量
2020/09/07 Python
Python为何不支持switch语句原理详解
2020/10/21 Python
数控个人求职信范文
2014/02/03 职场文书
大学生怎样写好自荐信
2014/02/25 职场文书
实习证明格式范文
2014/10/14 职场文书
2014小学语文教师个人工作总结
2014/12/03 职场文书
工程合作意向书范本
2015/05/09 职场文书
立项申请报告范本
2015/05/15 职场文书
2015年国庆晚会主持词
2015/07/01 职场文书
公司员工离职感言
2015/08/03 职场文书
Python time库的时间时钟处理
2021/05/02 Python
python如何为list实现find方法
2022/05/30 Python