深入理解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 has encountered an Access Violation
Jan 15 PHP
QQ登录 PHP OAuth示例代码
Jul 20 PHP
windows环境下php配置memcache的具体操作步骤
Jun 09 PHP
ueditor 1.2.6 使用方法说明
Jul 24 PHP
php去除字符串换行符示例分享
Feb 13 PHP
推荐一款PHP+jQuery制作的列表分页的功能模块
Oct 14 PHP
Laravel 5 框架入门(二)构建 Pages 的管理功能
Apr 09 PHP
thinkphp 验证码 的使用小结
May 07 PHP
[原创]PHP实现字节数Byte转换为KB、MB、GB、TB的方法
Aug 31 PHP
PHP+MySQL高并发加锁事务处理问题解决方法
Apr 30 PHP
php中如何执行linux命令详解
Nov 06 PHP
用php实现分页效果的示例代码
Dec 10 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编程之高级技巧——利用Mysql函数
2006/10/09 PHP
dedecms中常见问题修改方法总结
2007/03/21 PHP
gd库图片下载类实现下载网页所有图片的php代码
2012/08/20 PHP
WordPress中重置文章循环的rewind_posts()函数讲解
2016/01/11 PHP
PHP中单例模式的使用场景与使用方法讲解
2019/03/18 PHP
php的RSA加密解密算法原理与用法分析
2020/01/23 PHP
php计数排序算法的实现代码(附四个实例代码)
2020/03/31 PHP
javascript RadioButtonList获取选中值
2009/04/09 Javascript
JS仿百度搜索自动提示框匹配查询功能
2013/11/21 Javascript
jQuery使用ajaxSubmit()提交表单示例
2014/04/04 Javascript
js中 javascript:void(0) 用法详解
2015/08/11 Javascript
js中获取时间new Date()的全面介绍
2016/06/20 Javascript
AngularJS基础 ng-src 指令简单示例
2016/08/03 Javascript
VUE利用vuex模拟实现新闻点赞功能实例
2017/06/28 Javascript
vue-cli脚手架引入图片的几种方法总结
2018/03/13 Javascript
详解在React里使用&quot;Vuex&quot;
2018/04/02 Javascript
在vue项目中引入高德地图及其UI组件的方法
2018/09/04 Javascript
解决三元运算符 报错“SyntaxError: can''t assign to conditional expression”
2020/02/12 Javascript
vue.js实现h5机器人聊天(测试版)
2020/07/16 Javascript
JavaScript实现缓动动画
2020/11/25 Javascript
[01:20:38]完美世界DOTA2联赛 GXR vs IO 第一场 11.07
2020/11/09 DOTA
查看Python安装路径以及安装包路径小技巧
2015/04/28 Python
[原创]pip和pygal的安装实例教程
2017/12/07 Python
python 模拟银行转账功能过程详解
2019/08/06 Python
利用python、tensorflow、opencv、pyqt5实现人脸实时签到系统
2019/09/25 Python
python是否适合网页编程详解
2019/10/04 Python
Django配置文件代码说明
2019/12/04 Python
pyecharts绘制中国2020肺炎疫情地图的实例代码
2020/02/12 Python
Python3实现监控新型冠状病毒肺炎疫情的示例代码
2020/02/13 Python
Pytest如何使用skip跳过执行测试
2020/08/13 Python
俄罗斯宠物用品网上商店:ZooMag
2019/12/12 全球购物
2015年派出所民警工作总结
2015/04/24 职场文书
2019邀请函格式及范文
2019/05/20 职场文书
为什么MySQL选择Repeatable Read作为默认隔离级别
2021/07/26 MySQL
Vue3如何理解ref toRef和toRefs的区别
2022/02/18 Vue.js
Python 读取千万级数据自动写入 MySQL 数据库
2022/06/28 Python