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实现链结人气统计
Oct 09 PHP
PHP 分页原理分析,大家可以看看
Dec 21 PHP
php中实现记住密码自动登录的代码
Mar 02 PHP
PHP写UltraEdit插件脚本实现方法
Dec 26 PHP
用Simple Excel导出xls实现方法
Dec 06 PHP
PHP CURL获取返回值的方法
May 04 PHP
PHP中array_keys和array_unique函数源码的分析
Feb 26 PHP
PHP生成和获取XML格式数据的方法
Mar 04 PHP
深入剖析浏览器退出之后php还会继续执行么
May 17 PHP
Yii视图CGridView列表用法实例分析
Jul 12 PHP
如何修改Laravel中url()函数生成URL的根地址
Aug 11 PHP
PHP PDOStatement::getAttribute讲解
Feb 01 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网站基础优化方法小结
2008/09/29 PHP
php实现通过soap调用.Net的WebService asmx文件
2017/02/27 PHP
js 操作select和option常用代码整理
2012/12/13 Javascript
js控制iframe的高度/宽度让其自适应内容
2014/04/09 Javascript
处理文本部分内容的TextRange对象应用实例
2014/07/29 Javascript
jQuery搜索子元素的方法
2015/02/10 Javascript
基于JavaScript实现根据手机定位获取当前具体位置(X省X市X县X街道X号)
2015/12/29 Javascript
bootstrap中模态框、模态框的属性实例详解
2017/02/17 Javascript
深究AngularJS如何获取input的焦点(自定义指令)
2017/06/12 Javascript
vue 2.x 中axios 封装的get 和post方法
2018/02/28 Javascript
浅析Vue中method与computed的区别
2018/03/06 Javascript
JavaScript基于数组实现的栈与队列操作示例
2018/12/22 Javascript
微信小程序将页面按钮悬浮固定在底部的实现代码
2020/10/29 Javascript
[01:52]DOTA2完美大师赛Vega战队趣味视频——kpii老师小课堂
2017/11/25 DOTA
python查询mysql中文乱码问题
2014/11/09 Python
python将MongoDB里的ObjectId转换为时间戳的方法
2015/03/13 Python
用Python实现服务器中只重载被修改的进程的方法
2015/04/30 Python
Python实现数通设备端口使用情况监控实例
2015/07/15 Python
在windows系统中实现python3安装lxml
2016/03/23 Python
Python用 KNN 进行验证码识别的实现方法
2018/02/06 Python
python leetcode 字符串相乘实例详解
2018/09/03 Python
python实现dijkstra最短路由算法
2019/01/17 Python
python sklearn常用分类算法模型的调用
2019/10/16 Python
python分布式编程实现过程解析
2019/11/08 Python
Python hashlib模块实例使用详解
2019/12/24 Python
python中加背景音乐如何操作
2020/07/19 Python
Python基于pyjnius库实现访问java类
2020/07/31 Python
使用jupyter notebook运行python和R的步骤
2020/08/13 Python
ASOS英国官网:英国在线时装和化妆品零售商
2017/05/19 全球购物
HealthElement海外旗舰店:新西兰大卖场
2018/02/23 全球购物
如何选择使用结构还是类
2014/05/30 面试题
人力资源专员岗位职责
2014/01/30 职场文书
护理专业毕业生自我鉴定总结
2014/03/24 职场文书
项目投资意向书
2014/04/01 职场文书
亲属关系公证书
2014/04/08 职场文书
九年级语文教学反思
2016/03/03 职场文书