PHP使用Session遇到的一个Permission denied Notice解决办法


Posted in PHP onJuly 30, 2014

如果在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  root

而一般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 rm

另外, 可以看到, 在判别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_divisor

也就是说, 默认情况下, 差不多是100次能调用一次gc过程. 所以也就是小概率的可以看到这个Notice.

要关闭这个Notice, 只需要设置:

session.gc_probability = 0, 让s_gc完全没有运行的可能即可.

当然, 你也可以改变这个文件夹的权限…

PHP 相关文章推荐
比较全面的PHP数组的使用方法小结
Sep 23 PHP
php将时间差转换为字符串提示
Sep 07 PHP
使用swoole扩展php websocket示例
Feb 13 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(六)
Jun 23 PHP
ThinkPHP控制器间实现相互调用的方法
Oct 31 PHP
ThinkPHP提示错误Fatal error: Allowed memory size的解决方法
Feb 12 PHP
PHP删除指定目录中的所有目录及文件的方法
Feb 26 PHP
PHP面向对象详解(三)
Dec 07 PHP
详解PHP编码转换函数应用技巧
Oct 22 PHP
PHP数字前补0的自带函数sprintf 和number_format的用法(详解)
Feb 06 PHP
PHP使用file_get_contents发送http请求功能简单示例
Apr 29 PHP
PHP dirname简单使用代码实例
Nov 13 PHP
PHP伪静态Rewrite设置之APACHE篇
Jul 30 #PHP
PHP return语句的另一个作用
Jul 30 #PHP
php mb_substr()函数截取中文字符串应用示例
Jul 29 #PHP
php CI框架插入一条或多条sql记录示例
Jul 29 #PHP
两种设置php载入页面时编码的方法
Jul 29 #PHP
php ci框架中加载css和js文件失败的原因及解决方法
Jul 29 #PHP
php switch语句多个值匹配同一代码块应用示例
Jul 29 #PHP
You might like
PHP和JavaScrip分别获取关联数组的键值示例代码
2013/09/16 PHP
PHP实现的简易版图片相似度比较
2015/01/07 PHP
smarty循环嵌套用法示例分析
2016/07/19 PHP
详谈PHP面向对象中常用的关键字和魔术方法
2017/02/04 PHP
PHP执行linux命令6个函数代码实例
2020/11/24 PHP
发布一个高效的JavaScript分析、压缩工具 JavaScript Analyser
2007/11/30 Javascript
JavaScript入门教程(9) Document文档对象
2009/01/31 Javascript
Javascript中判断变量是数组还是对象(array还是object)
2013/08/14 Javascript
JavaScript截取字符串的Slice、Substring、Substr函数详解和比较
2014/03/20 Javascript
jquery 隐藏与显示tr标签示例代码
2014/06/06 Javascript
jQuery中的pushStack实现原理和应用实例
2015/02/03 Javascript
Windows系统中安装nodejs图文教程
2015/02/28 NodeJs
javascript实现通过表格绘制颜色填充矩形的方法
2015/04/21 Javascript
JS实现弹性菜单效果代码
2015/09/07 Javascript
iScroll.js 使用方法参考
2016/05/16 Javascript
非常酷炫的Bootstrap图片轮播动画
2016/05/27 Javascript
浅谈addEventListener和attachEvent的区别
2016/07/14 Javascript
使用Vue.js和Flask来构建一个单页的App的示例
2018/03/21 Javascript
封装微信小程序http拦截器过程解析
2019/08/13 Javascript
JavaScript生成随机验证码代码实例
2019/09/28 Javascript
定制FileField中的上传文件名称实例
2017/08/23 Python
django的登录注册系统的示例代码
2018/05/14 Python
django session完成状态保持的方法
2018/11/27 Python
基于python历史天气采集的分析
2019/02/14 Python
python3.6环境安装+pip环境配置教程图文详解
2019/06/20 Python
基于Python实现签到脚本过程解析
2019/10/25 Python
Python流程控制常用工具详解
2020/02/24 Python
html+css3实现的登录界面
2020/12/09 HTML / CSS
客服工作职责
2013/12/11 职场文书
走进敬老院活动总结
2014/07/10 职场文书
委托书怎样写
2014/08/30 职场文书
开除员工通知
2015/04/22 职场文书
清明节随笔
2015/08/15 职场文书
Python中Permission denied的解决方案
2021/04/02 Python
教你如何使用Python Tkinter库制作记事本
2021/06/10 Python
Mysql中一千万条数据怎么快速查询
2021/12/06 MySQL