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 STRING 陷阱原理说明
Jul 24 PHP
php运行出现Call to undefined function curl_init()的解决方法
Nov 02 PHP
php从数组中随机抽取一些元素的代码
Nov 05 PHP
在PHP上显示JFreechart画的统计图方法
Nov 03 PHP
ThinkPHP让分页保持搜索状态的方法
Jul 02 PHP
php在线解压ZIP文件的方法
Dec 30 PHP
PHP连接access数据库
Mar 27 PHP
关于PHP中字符串与多进制转换函数的实例代码
Nov 03 PHP
自写的利用PDO对mysql数据库增删改查操作类
Feb 19 PHP
laravel 实现设置时区的简单方法
Oct 10 PHP
laravel实现上传图片的两种方式小结
Oct 12 PHP
php设计模式之原型模式分析【星际争霸游戏案例】
Mar 23 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计算到指定日期还有多少天的方法
2015/04/14 PHP
必须收藏的php实用代码片段
2016/02/02 PHP
图文详解PHP环境搭建教程
2016/07/16 PHP
在Javascript中定义对象类别
2006/12/22 Javascript
js每次Title显示不同的名言
2008/09/25 Javascript
用Jquery实现多级下拉框无刷新的联动
2010/12/22 Javascript
原生js和jquery中有关透明度设置的相关问题
2014/01/08 Javascript
VS2008中使用JavaScript调用WebServices
2014/12/18 Javascript
jQuery获取同级元素的简单代码
2016/07/09 Javascript
JS触摸屏网页版仿app弹窗型滚动列表选择器/日期选择器
2016/10/30 Javascript
利用JavaScript在网页实现八数码启发式A*算法动画效果
2017/04/16 Javascript
React事件处理的机制及原理
2018/12/03 Javascript
基于Proxy的小程序状态管理实现
2019/06/14 Javascript
Vue select 绑定动态变量的实例讲解
2020/10/22 Javascript
[06:57]DOTA2-DPC中国联赛 正赛 Ehome vs PSG.LGD 选手采访
2021/03/11 DOTA
python with statement 进行文件操作指南
2014/08/22 Python
Python中easy_install 和 pip 的安装及使用
2017/06/05 Python
Python通过属性手段实现只允许调用一次的示例讲解
2018/04/21 Python
浅析Python数据处理
2018/05/02 Python
python实现逐个读取txt字符并修改
2018/12/24 Python
Python中常用的8种字符串操作方法
2019/05/06 Python
Python PIL图片添加字体的例子
2019/08/22 Python
Python requests.post方法中data与json参数区别详解
2020/04/30 Python
为什么是 Python -m
2020/06/19 Python
什么是TCP/IP
2014/07/27 面试题
CSS实现fullpage.js全屏滚动效果的示例代码
2021/03/24 HTML / CSS
廉政教育心得体会
2014/01/01 职场文书
总经理助理工作职责
2014/02/06 职场文书
网吧最新创业计划书范文
2014/03/27 职场文书
十佳标兵事迹材料
2014/08/18 职场文书
我为党旗添光彩演讲稿
2014/09/10 职场文书
毕业实习证明(4篇)
2014/10/28 职场文书
初中生毕业评语
2014/12/29 职场文书
大学生军训感言
2015/08/01 职场文书
网络研修心得体会
2016/01/08 职场文书
html5调用摄像头实例代码
2021/06/28 HTML / CSS