PHP在NFS共享目录中创建空会话


PHP creates empty session in NFS shared directory

我在OSX主机上的Vagrant VM上运行Ubuntu 12.04。

这里是用来挂载文件夹的Vagrant配置:

config.vm.synced_folder "/var/projects", "/projects", type: "nfs"

我发现PHP不能在NFS共享目录上正常创建会话。

下面是test.php脚本:

session_save_path('/projects/sessions');
session_start();
file_put_contents('/projects/sessions/file.txt', 'TEST');

下面是执行的输出:

$ php test.php 
PHP Warning:  Unknown: Failed to write session data (files). Please verify that the current setting of session.save_path is correct (/project/sessions) in Unknown on line 0

下面是执行后的结果:

$ ls -l
total 8
-rw------- 1 502 dialout   0 Jul 21 10:13 sess_0p6bt4g3o0sofi3b7p6016jtg7
-rw-rw-r-- 1 502 dialout   4 Jul 21 10:13 file.txt
-rw-rw-r-- 1 502 dialout 164 Jul 21 10:12 test.php

可以看到,会话文件是空的,并且是用奇怪的权限创建的。因此,txt文件的创建没有错误。

我试过PHP 5.4和5.5

还有什么建议可以试试吗?

提前感谢

写会话数据

我也遇到过这个问题:(

不幸的是,我还没能弄清楚为什么会发生这种情况。它与PHP如何将会话数据与漫游客户机中的NFS同步文件夹结合在一起写有关。(所有其他写操作正常运行,它特定于会话写)

我最终通过将会话存储在同步文件夹之外来解决这个问题。在我的例子中,我只使用/tmp。对于漫游客户机,这样做的安全风险是可以接受的,因为它只在本地机器上运行。我不建议在实际的(生产)服务器上这样做,但是在那里你不会有这个问题;)

Owner/group

文件的所有者(502)/组(dialout) &对于OS X主机上的漫游客户端来说,同步文件夹内的目录是正常的。

502是OS X主机上用户的uid。该用户的gid设置为20 (staff),这对于OS X用户来说是正常的。当通过NFS挂载已同步的文件夹时,相同的uid &gid将出现在流浪汉来宾中。在这里,uid 502没有映射到用户,这就是为什么在执行ls -l时会显示502的原因。gid 20被映射到组dialout,所以这就是为什么会显示。

我之所以提到这一点,是因为你可以在互联网上找到很多资源,指出这个"奇怪的"用户/组信息是写入问题的根源,但它不是。这一点也不"奇怪"(但对于OS X主机上的NFS同步文件夹来说是完全正常的),并且不会导致写入问题。您可以使用file_put_contents()编写文件的事实证明。

不同的会话处理程序

默认情况下,PHP将使用files作为session.save_handler指令的值,这将导致会话被存储在文件系统中。

某些扩展(如Sqlite, Memcached, Redis等)将注册不同的处理程序供您使用。可以将session.save_handler设置为sqlitememcachedredis等。关于如何配置它们,请参考相应的文档。

或者您可以通过将session.save_handler设置为user来使用自定义处理程序。然后你可以实现任何你喜欢的东西。这是在MySQL数据库中存储会话的常用方法。这些文档应该可以帮助你开始:

  • 自定义会话处理器
  • session_set_save_handler
  • session.save_handler

我以前遇到过这个问题,我通过改变我的项目目录的权限来解决它。

我相信如果您在vagrantFile中更新驱动器映射行,您的问题将会消失。使用nfs映射的文档可以在:https://docs.vagrantup.com/v2/synced-folders/nfs.html

在windows上,最简单的解决方案是将php降级到5.3,这是ubuntu 12.04的默认版本,它工作没有任何问题。在我升级到5.4和5.5之后,它停止工作了。

另一个解决方法是通过删除vagrant配置中的synced_folder行并使用provision文件添加mount cifs来禁用共享文件夹。

mount -t cifs -o username=myusername,password=mypass //192.168.0.88/projects/new_project/public_html/ /home/new_site/public_html/

您必须首先在您的主机上创建smb共享