gpt4 book ai didi

php - 所有项目通用的 session.save_handler

转载 作者:行者123 更新时间:2023-12-02 14:30:42 24 4
gpt4 key购买 nike

我正在使用 vagrant 虚拟机进行本地 PHP 开发,我注意到使用 vagrant-winnfsd 插件时存在 session 写入问题。该插件很好地满足了我的需求,这就是为什么我不想重新配置 vagrant,而是解决读/写问题。我不知道问题的根源,但是和描述的一模一样here 。对我来说,SessionHandler::read() 还需要大约 120 秒才能完成每个请求。

因此,正如作者建议的那样,重新配置 session 处理程序以使用 RDBM 或 Memcache 存储是有意义的。这听起来很合理,但我不想在每个项目中都这样做,我只想在 php.ini 中配置一次,因为它有 session.save_handler 参数并且可以设置为数据库或内存缓存。

我不介意有一个 PHP 类包含所有 ::read()::write() 和其他方法,主要是将这段代码放在一个地方。

这可能吗?

更新:我找到了原因,并且非常感谢@Jasper N. Brouwer,他们将其存储在 NFS 同步文件夹中。原因是我没有将 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();
}

但是,只是出于好奇和为了更容易调试,因为我们现在有了这个赏金,我仍然发现整个 PHP 服务器的公共(public) session 保存处理程序是一个好主意。如果我必须将其保存到数据库中,然后可以使用 GUI 工具在数据库中实时查看所有项目的 session 数据,这在开发中可能很有用。也许,可以使用 auto_prepend_file 设置来做到这一点?并在那里定义保存处理程序,但我不确定如何禁止稍后在任何项目代码中覆盖它。

最佳答案

session

一个更简单的解决方案是继续使用files session 保存处理程序,但让它使用一个不是 Vagrant“同步文件夹”的目录。

换句话说,将session.save_path设置为/tmp。这可以是任何目录,只要它不是同步文件夹(例如 /vagrant)。您确实可以在 php.ini 中执行此操作。

最好使用实际上是共享内存目录的目录 (/dev/shm),它是内存存储(而不是磁盘上)。在大多数 Linux 发行版上,/tmp 实际上是 /dev/shm 内的一个文件夹。

PS:我遇到了类似的问题, session 写入会产生空文件。我也无法找到这个问题的根源(除了它与使用 NFS 的 Vagrant 同步文件夹有关),所以过了一段时间我放弃了搜索,只是做了我上面描述的事情。

其他大量写入操作

由于 Vagrant NFS 挂载速度相对较慢,因此我建议在同步文件夹之外执行其他大量写入操作。

写入密集型事物的示例是缓存系统:

  • 原则 2 可以使用文件缓存驱动程序进行元数据、查询和结果缓存。
  • 原则 2 将以开发模式编写代理。
  • Twig 会将模板“编译”为原始 PHP 文件。
  • Symfony 2 将在文件中缓存各种内容。
  • 还有很多其他

另一个例子是记录器。日志通常会写入文件,这种情况经常发生。

不幸的是,没有真正的方法可以在服务器范围内配置这些目录,因为这完全取决于使用什么组件,需要配置什么,这是非常特定于项目的。

可能的 Symfony 2 解决方案

您可以尝试某种 hack,让 Symfony 2 使用环境变量来使用缓存和日志目录。

像这样设置环境变量:

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;

然后您可以编辑 AppKernel.phpgetCacheDir()getLogDir() 方法,如下所示:

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 项目的缓存和日志目录。

对于其他项目,您可以执行类似的操作。

但是您必须对项目本身进行一些调整。因为这不是 native PHP 功能(例如 session.save_path ),因此无法通过 PHP 配置(仅 php.ini)来控制它)。

关于php - 所有项目通用的 session.save_handler,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30709526/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com