深入理解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设计模式 State (状态模式)
Jun 26 PHP
PHP垃圾回收机制引用计数器概念分析
Jun 24 PHP
php利用新浪接口查询ip获取地理位置示例
Jan 20 PHP
PHP打开和关闭文件操作函数总结
Nov 18 PHP
php程序总是提示验证码输入有误解决方案
Jan 07 PHP
PHP中curl_setopt函数用法实例分析
Apr 16 PHP
php检测图片主要颜色的方法
Jul 01 PHP
php无法连接mysql数据库的正确解决方法
Jul 01 PHP
php集成动态口令认证
Jul 21 PHP
Yii2压缩PHP中模板代码的输出问题
Aug 28 PHP
php-fpm重启导致的程序执行中断问题详解
Apr 29 PHP
基于Laravel 多个中间件的执行顺序详解
Oct 21 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初学者头疼问题总结
2006/07/08 PHP
php与XML、XSLT、Mysql的结合运用实现代码
2009/11/19 PHP
使用PHP如何实现高效安全的ftp服务器(一)
2015/12/20 PHP
Yii2框架RESTful API 格式化响应,授权认证和速率限制三部分详解
2016/11/10 PHP
PHP与JavaScript针对Cookie的读写、交互操作方法详解
2017/08/07 PHP
HTML复选框和单选框 checkbox和radio事件介绍
2012/12/12 Javascript
JS跨域解决方案之使用CORS实现跨域
2016/04/14 Javascript
React Native实现简单的登录功能(推荐)
2016/09/19 Javascript
wap手机端解决返回上一页的js实例
2016/12/08 Javascript
详解require.js配置路径的用法和css的引入
2017/09/06 Javascript
浅谈layui 数据表格前后台传值的问题
2019/09/12 Javascript
vue实现全屏滚动效果(非fullpage.js)
2020/03/07 Javascript
nodejs+koa2 实现模仿springMVC框架
2020/10/21 NodeJs
[01:19:23]2018DOTA2亚洲邀请赛 4.5 淘汰赛 Mineski vs VG 第二场
2018/04/06 DOTA
windows下python模拟鼠标点击和键盘输示例
2014/02/28 Python
用python + hadoop streaming 分布式编程(一) -- 原理介绍,样例程序与本地调试
2014/07/14 Python
以Python的Pyspider为例剖析搜索引擎的网络爬虫实现方法
2015/03/30 Python
Python中装饰器高级用法详解
2017/12/25 Python
Python3.7 新特性之dataclass装饰器
2019/05/27 Python
用python给自己做一款小说阅读器过程详解
2019/07/11 Python
Python爬虫爬取博客实现可视化过程解析
2020/06/29 Python
Python 中如何写注释
2020/08/28 Python
经典c++面试题五
2014/12/17 面试题
捐书寄语赠言
2014/01/18 职场文书
2014元旦晚会策划方案
2014/02/19 职场文书
《口技》教学反思
2014/02/21 职场文书
食堂采购员岗位职责
2014/03/17 职场文书
《欢乐的泼水节》教学反思
2014/04/22 职场文书
竞聘演讲稿精彩开头和结尾
2014/05/14 职场文书
采购员岗位职责
2015/02/03 职场文书
文言文辞职信
2015/02/28 职场文书
2015年双拥工作总结
2015/04/08 职场文书
英语演讲开场白
2015/05/29 职场文书
行政后勤人员工作计划应该怎么写?
2019/08/16 职场文书
Java数据开发辅助工具Docker与普通程序使用方法
2021/09/15 Java/Android
git中cherry-pick命令的使用教程
2022/06/25 Servers