我正在使用vagrant虚拟机进行本地PHP开发,我注意到使用vagrant-winnfsd插件时存在会话写入问题。该插件满足我的需求,这就是为什么我不想重新配置vagrant,而是解决读/写问题。我不知道问题的根源,但它与描述的here完全相同。对我来说,SessionHandler::read()
每次请求也需要大约120秒才能完成。
正如作者所建议的那样,重新配置会话处理程序以使用RDDBM或Memcache存储是有意义的。这听起来很合理,但我不想在每个项目中都这样做,我只想在php.ini中配置一次,因为它有session.save_handler
参数,可以在那里设置为数据库或memcache。
我不介意拥有一个包含所有::read()
,::write()
和其他方法的PHP类,主要的是将代码放在一个地方。
这可能吗?
更新:我找到了原因并非常感谢@Jasper N. Brouwer他们存储在NFS sync'd文件夹中。原因是我没有将prod
环境添加到AppKernel.php“vagrant”修复程序中。所以它曾经是:
public function getCacheDir()
{
if (in_array($this->environment, array('dev', 'test', ''))) {
return '/run/shm/appname/cache/' . $this->environment;
}
return parent::getCacheDir();
}
public function getLogDir()
{
if (in_array($this->environment, array('dev', 'test'))) {
return '/run/shm/appname/logs';
}
return parent::getLogDir();
}
在dev
env中没问题,但在prod
中没有。应该是:
public function getCacheDir()
{
if (in_array($this->environment, array('dev', 'test', 'prod'))) {
return '/run/shm/appname/cache/' . $this->environment;
}
return parent::getCacheDir();
}
public function getLogDir()
{
if (in_array($this->environment, array('dev', 'test', 'prod'))) {
return '/run/shm/appname/logs';
}
return parent::getLogDir();
}
HOWEVER ,只是出于好奇和更容易调试,因为我们现在有这个赏金,我仍然发现整个PHP服务器的公共会话保存处理程序是一个好主意。如果我必须将其保存到数据库中,然后可以使用我的GUI工具在数据库中实时查看所有项目的会话数据,这在开发中可能很有用。也许,使用auto_prepend_file
设置可以做到这一点?并在那里定义save hanlder,但我不知道如何在任何项目代码中禁止覆盖它。
答案 0 :(得分:4)
更简单的解决方案是继续使用files
会话保存处理程序,但让它使用不一个Vagrant"同步文件夹的目录"。
换句话说,例如,将session.save_path
设置为/tmp
。这可以是任何目录,只要它不是同步文件夹(如/vagrant
)。您确实可以在php.ini
。
使用一个实际上是共享内存目录(/dev/shm
)的目录会更好,这是一个内存存储(不在磁盘上)。在大多数Linux发行版/tmp
上实际上是/dev/shm
内的文件夹。
PS:我遇到类似的问题,会话写入会产生空文件。我也无法找到这个问题的根源(除了它与使用NFS的Vagrant同步文件夹有关),所以过了一段时间我放弃了搜索,只是做了我上面描述的。
由于Vagrant NFS挂载相对较慢,我建议在同步文件夹之外执行其他写入操作。
重写事物的例子是缓存系统:
另一个例子是记录器。日志通常会写入文件,这种情况会发生很多。
不幸的是,在服务器范围内没有真正的方法来配置这些目录,因为这完全取决于使用的组件,需要配置的内容,这是特定于项目的。
你可以尝试一种破解让Symfony 2使用环境变量使用cache-和logs-directory。
设置如下的环境变量:
export VENDORNAME_PHP_CACHE_ROOT_DIR='/dev/shm/vendorname/cache'
export VENDORNAME_PHP_LOGS_ROOT_DIR='/dev/shm/vendorname/logs'
这将确保CLI工具可以选择这些变量。
您可能希望在.bashrc
或类似的内容中执行此操作。
您可能必须在网络服务器的配置中复制此内容:
对于Apache
SetEnv VENDORNAME_PHP_CACHE_ROOT_DIR /dev/shm/vendorname/cache
SetEnv VENDORNAME_PHP_LOGS_ROOT_DIR /dev/shm/vendorname/logs
对于Nginx
fastcgi_param VENDORNAME_PHP_CACHE_ROOT_DIR /dev/shm/vendorname/cache;
fastcgi_param VENDORNAME_PHP_LOGS_ROOT_DIR /dev/shm/vendorname/logs;
然后您可以像这样编辑getCacheDir()
getLogDir()
和AppKernel.php
方法:
public function getCacheDir()
{
if ($dir = $this->getDir('VENDORNAME_PHP_CACHE_ROOT_DIR')) {
return $dir;
}
return parent::getCacheDir();
}
public function getLogDir()
{
if ($dir = $this->getDir('VENDORNAME_PHP_LOGS_ROOT_DIR')) {
return $dir;
}
return parent::getLogDir();
}
private function getDir($variable)
{
if (!in_array($this->environment, array('dev', 'test'))) {
return;
}
if (!($rootDir = getenv($variable))) {
return;
}
return sprintf('%s/appname/%s', $rootDir, $this->environment);
}
现在,您可以通过这些环境变量控制所有Symfony 2项目的缓存和日志目录。
对于其他项目,您可以做类似的事情。
但是你必须在项目中做一些调整。因为这是不本机PHP功能(如session.save_path
所示),所以无法通过PHP配置来控制它(仅php.ini
)。