PHP 7用户会话问题 - 初始化存储模块失败

8
在使用PHP 7.0版本时,与各种PHP框架的会话驱动程序存在漏洞。我最初在使用CodeIgniter数据库驱动程序时遇到了这个问题,并认为这是一个CodeIgniter的问题,但后来我在多个会话驱动程序和多个框架中都遇到了这个问题。此时,我已经安全地得出结论,会话驱动程序的类型是无关紧要的——似乎在随机情况下,应用程序将崩溃并且日志(我尝试过Apache和php-fpm + nginx)填满以下内容:
PHP致命错误:session_start():无法初始化存储模块:用户(路径:[我在php.ini路径中设置的任何内容])
我正在使用的驱动程序不使用php.ini中设置的值,无论我是否在php.ini中将session.save_handler设置为files、redis等,也无论我设置的路径是什么(如果是redis,则为Redis服务器,启用文件的完全可写文件夹),都会出现错误。这里的路径不应该被访问,除非在框架外调用了本地的“session_start()”。此外,在框架外调用“session_start()”可以正常工作……因此显然PHP可以访问该路径。就好像在某些时候,会话驱动程序成为了框架驱动程序和php.ini中设置的任何内容的混合体。错误消息总是将“user”作为session.save_handler,因此显然这不是从php.ini中提取的……但路径是。为什么会发生这种情况?这是一种难以描述的问题,直到你经历过它……而且很难复制,因为即使对于数百个会话,所有东西似乎都正常工作(直到突然停止工作)。重启Apache也无法纠正这个问题——这里有许多问题,我最终只能重新启动机器以避免停机时间。显然,PHP 7机器现在将被从负载均衡器轮换中移除……但我希望现在已经解决了问题。
我在自己编译的PHP 7.0 RC5、RC6和RC8上以及Ubuntu 15.10 Wily(7.0.0-2+deb.sury.org~wily+1)上的最新Ondřej Surý PPA上遇到了这个问题。我在CodeIgniter和Symfony上遇到了这个问题,并且无论框架中使用的驱动程序类型(文件、数据库、redis)或在php.ini中设置的session.save_handler如何(应该与此无关,但只是想提一下),我都遇到了这个问题。我不断尝试各种组合并将事物扔到野外,但这个问题每次都会发生(有时需要12个小时以上,具体取决于网站的流量)。
感谢您提供的任何帮助!我愿意尝试任何建议。

你是否已经在 http://bugs.php.net/ 上报告了这个错误? - Andrea
只需添加正确的路径来存储会话。 例如:进入配置文件并替换 $config['sess_save_path'] = NULL; 为 $config['sess_save_path'] = APPPATH . 'cache/session/';别忘了将Cache文件夹设置为0777权限。 - Ricky Harerri
14个回答

0

我相信我已经找到了问题的原因,我将关闭这个问题。基本上,当框架会话驱动程序/配置出现问题(SQL连接超过限制、Redis内存不足等)时,它会尝试使用在php.ini中设置的sess.save_path,同时仍然使用框架会话驱动程序。因此,除非框架驱动程序与php.ini中默认的sess.save_path兼容,否则会出现此错误。对我来说,也应该回归到php.ini中的sess.save_handler……但如果这是一个问题,显然还有更大的应用程序配置问题需要解决。

这个错误本身并没有破坏会话……它是框架会话驱动程序的潜在问题。我感觉很愚蠢……但日志基本上让我走了一条歪路。重启nginx或Apache都无法解决问题,因为问题出在其他地方。我认为,可用的PHP 7 Redis库和SQL问题仍然存在问题。在似乎尝试了许多组合并得到相同结果后,问题变得更加神秘。在PHP 7上仍然会出现奇怪的Redis会话错误,但正如我所说,PHP 7 Redis库还不够成熟。


1
既然你打了“codeigniter”的标签,我就假设这是你所说的“框架”。在这种情况下,你的结论是不准确的——CodeIgniter不会“恢复”使用sess.save_path;它会将其设置为你在配置中放置的内容,并始终使用它。 - Narf

0

这种情况只会发生在session_save_path无效的情况下,如果您将会话数据存储在数据库中,则必须创建会话表以便CI保存数据,否则您将遇到此错误。希望能帮助到某些人。


0

我们遇到了一个类似的问题,当我们使用 session_set_save_handler 设置自己的自定义处理器以使用Memcached时,我们一直收到以下错误:

Warning: session_write_close(): Failed to write session data (user). Please verify that the current setting of session.save_path is correct (/var/lib/php/7.0/session) in Unknown on line 0

原来,“write”函数需要返回布尔值(就像“start”一样),但它是session_set_save_handler的唯一一个没有在 PHP 官方文档中提到返回值的函数。因此,尽管看起来像是恢复为默认的会话处理程序,但实际上只是为默认的会话处理程序提供了 错误

错误和文档页面都不能帮助我们找到解决方案...


0

这个错误是由于未定义的会话路径引起的。
打开 application/config/config.php 文件的第 383 行。
将下面的行替换为
$config['sess_save_path'] = APPPATH . 'cache/session/';
而不是
$config['sess_save_path'] = NULL;
别忘了给 cache/session 文件夹赋予写入权限。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接