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 构造函数construct的前下划线是双的_
Dec 08 PHP
php统计文件大小,以GB、MB、KB、B输出
May 29 PHP
PHP获取MAC地址的函数代码
Sep 11 PHP
深入PHP异步执行的详解
Jun 03 PHP
Fatal error: session_start(): Failed to initialize storage module: files问题解决方法
May 04 PHP
PHP中读取文件的8种方法和代码实例
Aug 05 PHP
php+mysql查询优化简单实例
Jan 13 PHP
php中preg_replace_callback函数简单用法示例
Jul 21 PHP
PHP实现上传多文件示例代码
Feb 20 PHP
PHP计算近1年的所有月份
Mar 13 PHP
laravel 模型查询按照whereIn排序的示例
Oct 16 PHP
thinkphp5 + ajax 使用formdata提交数据(包括文件上传) 后台返回json完整实例
Mar 02 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
一个显示天气预报的程序
2006/10/09 PHP
CI框架中zip类应用示例
2014/06/17 PHP
WordPress中用于获取及自定义头像图片的PHP脚本详解
2015/12/17 PHP
CI框架集成Smarty的方法分析
2016/05/17 PHP
用javascript实现给出的盒子的序列是否可连为一矩型
2007/08/30 Javascript
JavaScript Event学习第六章 事件的访问
2010/02/07 Javascript
JavaScript使用function定义对象并调用的方法
2015/03/23 Javascript
JS文字球状放大效果代码分享
2015/08/19 Javascript
js实现的彩色方块飞舞奇幻效果
2016/01/27 Javascript
jQuery绑定事件-多种实现方式总结
2016/05/09 Javascript
对js中回调函数的一些看法
2016/08/29 Javascript
HTML5基于Tomcat 7.0实现WebSocket连接并实现简单的实时聊天
2016/10/31 Javascript
Jquery中.bind()、.live()、.delegate()和.on()之间的区别详解
2017/08/01 jQuery
Echarts基本用法_动力节点Java学院整理
2017/08/11 Javascript
VSCode 配置React Native开发环境的方法
2017/12/27 Javascript
jQuery实现的页面详情展开收起功能示例
2018/06/11 jQuery
详解express使用vue-router的history踩坑
2019/06/05 Javascript
ES6基础之数组和对象的拓展实例详解
2019/08/22 Javascript
Vue 实现html中根据类型显示内容
2019/10/28 Javascript
详解微信小程序动画Animation执行过程
2020/09/23 Javascript
Electron+vue从零开始打造一个本地播放器的方法示例
2020/10/27 Javascript
Python2和Python3中print的用法示例总结
2017/10/25 Python
python中set()函数简介及实例解析
2018/01/09 Python
Python3对称加密算法AES、DES3实例详解
2018/12/06 Python
Django将默认的SQLite更换为MySQL的实现
2019/11/18 Python
Python sys模块常用方法解析
2020/02/20 Python
python中编写函数并调用的知识点总结
2021/01/13 Python
CSS3实现水平居中、垂直居中、水平垂直居中的实例代码
2020/02/27 HTML / CSS
豆腐の盛田屋官网:日本自然派的豆乳面膜、肥皂、化妆水、乳液等
2016/10/08 全球购物
个人课题方案
2014/05/08 职场文书
2014教育局对照检查材料思想汇报
2014/09/23 职场文书
承诺函范文
2015/01/21 职场文书
综合素质自我评价评语
2015/03/06 职场文书
Golang 空map和未初始化map的注意事项说明
2021/04/29 Golang
MySQL脏读,幻读和不可重复读
2022/05/11 MySQL
SpringBoot项目部署到阿里云服务器的实现步骤
2022/06/28 Java/Android