php – Drupal 8覆盖会话管理
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了php – Drupal 8覆盖会话管理,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4924字,纯文字阅读大概需要8分钟。
内容图文
![php – Drupal 8覆盖会话管理](/upload/InfoBanner/zyjiaocheng/727/7f2c9196e9dc467ebd07ebbbf85b8c5e.jpg)
我想覆盖drupals核心会话管理而不是我自己,而是将会话保存到Redis而不是数据库.
谷歌搜索之后没有太多事情要做,除了这个:
https://www.drupal.org/project/session_proxy
唯一的问题是与Drupal 8不兼容,我只想保存到Redis我不需要任何其他处理程序.
在Symfony中,我创建了一个会话处理程序服务,但在Drupal 8中似乎更加棘手.
有关如何进行的任何建议?
谢谢
解决方法:
以下是我认为在不依赖第三方模块或任何其他插件的情况下解决此问题的最简单方法是覆盖Drupals核心SessionHandler类.
首先在我的模块中,我创建了一个ServiceProvider类,它指示容器用我自己的方法重新定义核心SessionHandler类定义.我不需要数据库连接服务,因此我确保只将请求堆栈传递给构造函数.
<?php
namespace Drupal\my_module;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceProviderBase;
use Symfony\Component\DependencyInjection\Reference;
class OoAuthServiceProvider extends ServiceProviderBase
{
/**
* {@inheritdoc}
*/
public function alter(ContainerBuilder $container)
{
$container->getDefinition('session_handler.storage')
->setClass('Drupal\my_module\SessionHandler')
->setArguments([
new Reference('request_stack')
]);
}
}
然后我继续创建自己的Redis SessionHandler:
<?php
namespace Drupal\my_module;
use Drupal\Component\Utility\Crypt;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Utility\Error;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy;
/**
* Default session handler.
*/
class SessionHandler extends AbstractProxy implements \SessionHandlerInterface {
use DependencySerializationTrait;
/**
* The request stack.
*
* @var RequestStack
*/
protected $requestStack;
/**
* @var \Redis
*/
protected $redis;
/**
* SessionHandler constructor.
*
* @param RequestStack $requestStack
*/
public function __construct(RequestStack $requestStack)
{
$this->requestStack = $requestStack;
// TODO: Store redis connection details in config.
$this->redis = (new PhpRedis())->getClient('redis-host', 6379);
}
/**
* {@inheritdoc}
*/
public function open($savePath, $name)
{
return true;
}
/**
* {@inheritdoc}
*/
public function read($sid)
{
$data = '';
if (!empty($sid)) {
$query = $this->redis->get(Crypt::hashBase64($sid));
$data = unserialize($query);
}
return (string) $data['session'];
}
/**
* {@inheritdoc}
*/
public function write($sid, $value)
{
// The exception handler is not active at this point, so we need to do it
// manually.
var_dump(['Value', $value]);
try {
$request = $this->requestStack->getCurrentRequest();
$fields = [
'uid' => $request->getSession()->get('uid', 0),
'hostname' => $request->getClientIP(),
'session' => $value,
'timestamp' => REQUEST_TIME,
];
$this->redis->set(
Crypt::hashBase64($sid),
serialize($fields),
(int) ini_get("session.gc_maxlifetime")
);
return true;
}
catch (\Exception $exception) {
require_once DRUPAL_ROOT . '/core/includes/errors.inc';
// If we are displaying errors, then do so with no possibility of a
// further uncaught exception being thrown.
if (error_displayable()) {
print '<h1>Uncaught exception thrown in session handler.</h1>';
print '<p>' . Error::renderExceptionSafe($exception) . '</p><hr />';
}
return true;
}
}
/**
* {@inheritdoc}
*/
public function close()
{
return true;
}
/**
* {@inheritdoc}
*/
public function destroy($sid)
{
// Delete session data.
$this->redis->delete(Crypt::hashBase64($sid));
return true;
}
/**
* {@inheritdoc}
*/
public function gc($lifetime)
{
// Redundant method when using Redis. You no longer have to check the session
// timestamp as the session.gc_maxlifetime is set as TTL on write.
return true;
}
}
在我自己的SessionHandler实现中使用的PhpRedis只是一个小实用程序类,用于处理与Redis的连接.
<?php
namespace Drupal\my_module;
/**
* Class PhpRedis
* @package Drupal\oo_auth
*/
class PhpRedis implements ClientInterface
{
/**
* {@inheritdoc}
*/
public function getClient($host = null, $port = null, $base = null, $password = null)
{
$client = new \Redis();
$client->connect($host, $port);
if (isset($password)) {
$client->auth($password);
}
if (isset($base)) {
$client->select($base);
}
// Do not allow PhpRedis serialize itself data, we are going to do it
// oneself. This will ensure less memory footprint on Redis size when
// we will attempt to store small values.
$client->setOption(\Redis::OPT_SERIALIZER, \Redis::SERIALIZER_NONE);
return $client;
}
/**
* {@inheritdoc}
*/
public function getName() {
return 'PhpRedis';
}
}
<?php
namespace Drupal\my_module;
/**
* Interface ClientInterface
* @package Drupal\oo_auth
*/
interface ClientInterface
{
/**
* Get the connected client instance.
*
* @param null $host
* @param null $port
* @param null $base
*
* @return mixed
*/
public function getClient($host = NULL, $port = NULL, $base = NULL);
/**
* Get underlying library name used.
*
* This can be useful for contribution code that may work with only some of
* the provided clients.
*
* @return string
*/
public function getName();
}
没有建议的文档(我可以找到),它为您提供了一个如何使用Redis(这实际上可以与任何数据存储区一起使用)作为Drupal安装的会话存储的示例.有关于如何使用其他第三方模块启动和运行的帖子很好,但我不想要额外的毛病.
内容总结
以上是互联网集市为您收集整理的php – Drupal 8覆盖会话管理全部内容,希望文章能够帮你解决php – Drupal 8覆盖会话管理所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。