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初学者们头痛的十四个问题
Jan 15 PHP
Smarty+QUICKFORM小小演示
Feb 25 PHP
一步一步学习PHP(2)――PHP类型
Feb 15 PHP
PHP图片等比缩放类SimpleImage使用方法和使用实例分享
Apr 10 PHP
php 伪静态之IIS篇
Jun 02 PHP
php编写简单的文章发布程序
Jun 18 PHP
PHP实现文件上传与下载实例与总结
Mar 13 PHP
thinkphp3.2中实现phpexcel导出带生成图片示例
Feb 14 PHP
修改yii2.0用户登录使用的user表为其它的表实现方法(推荐)
Aug 01 PHP
PHP自定义序列化接口Serializable用法分析
Dec 29 PHP
Laravel框架文件上传功能实现方法示例
Apr 16 PHP
laravel框架中表单请求类型和CSRF防护实例分析
Nov 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完全过滤HTML,JS,CSS等标签
2009/01/16 PHP
fleaphp crud操作之findByField函数的使用方法
2011/04/23 PHP
php获取POST数据的三种方法实例详解
2016/12/20 PHP
PHP扩展mcrypt实现的AES加密功能示例
2019/01/29 PHP
使用ucenter实现多站点同步登录的讲解
2019/03/21 PHP
任意位置显示html菜单
2007/02/01 Javascript
JQuery 选择器 xpath 语法应用
2010/05/13 Javascript
Javascript在IE下设置innerHTML时出现未知的运行时错误的解决方法
2011/01/12 Javascript
原生Js页面滚动延迟加载图片实现原理及过程
2013/06/24 Javascript
jQuery过滤HTML标签并高亮显示关键字的方法
2015/08/07 Javascript
jquery实现简单实用的弹出层效果代码
2015/10/15 Javascript
在Web项目中引入Jquery插件报错的完美解决方案(图解)
2016/09/19 Javascript
CSS+jQuery实现简单的折叠菜单
2016/12/20 Javascript
jQuery 开发之EasyUI 添加数据的实例
2017/09/26 jQuery
微信小程序url与token设置详解
2017/09/26 Javascript
Vue用v-for给src属性赋值的方法
2018/03/03 Javascript
解决Vue.js父组件$on无法监听子组件$emit触发事件的问题
2018/09/12 Javascript
vue+element-ui实现表格编辑的三种实现方式
2018/10/31 Javascript
微信小程序实现点击按钮后修改颜色
2019/12/05 Javascript
基于NodeJS开发钉钉回调接口实现AES-CBC加解密
2020/08/20 NodeJs
vue-cli脚手架的.babelrc文件用法说明
2020/09/11 Javascript
[02:43]DOTA2英雄基础教程 半人马战行者
2014/01/13 DOTA
Python中使用scapy模拟数据包实现arp攻击、dns放大攻击例子
2014/10/23 Python
Python抓取百度查询结果的方法
2015/07/08 Python
图文详解WinPE下安装Python
2016/05/17 Python
Python自定义函数定义,参数,调用代码解析
2017/12/27 Python
Python-接口开发入门解析
2019/08/01 Python
keras 自定义loss损失函数,sample在loss上的加权和metric详解
2020/05/23 Python
深入了解NumPy 高级索引
2020/07/24 Python
python 实现图片修复(可用于去水印)
2020/11/19 Python
PyQt实现计数器的方法示例
2021/01/18 Python
用JAVA SOCKET编程,读服务器几个字符,再写入本地显示
2012/11/25 面试题
工厂厂长岗位职责
2013/11/08 职场文书
运动会通讯稿50字
2014/01/30 职场文书
王老吉广告词
2014/03/20 职场文书
破坏寝室公物检讨书
2014/11/17 职场文书