为匿名用户存储数据/会话


12

我正在一家商店里工作,对于购物车,我需要在付款之前存储物品。

  $tempstore = \Drupal::service('user.private_tempstore')->get('boutique');
  $tempstore->set('poids', $form_state->getValue('poids'));

我来看看以下用户服务:

pivate_tempstore和shared_tempstore

但这仅对验证用户有效。

我可以用来存储数据吗?$ _SESSION吗?还是Drupal 8为此提供服务?


我正在使用cookie。我有要验证的标识符和哈希Cookie,然后将标识符与所需的配对。我不使用会话,因为D8也停止将其用于匿名用户。

好的,为什么不使用$ _SESSION呢?
凯文

Answers:


11

在Drupal 8中,可以从请求中访问会话变量:

$session = \Drupal::request()->getSession();

如果要在会话中进行设置,可以执行以下操作:

$profile = 'Person';
$session->set('profile', $profile);

或获取会话变量:

$details = $session->get('profile');

1
我将尝试一下,以便您可以存储数组?
凯文

1
是的,您可以存储数组,我更改了代码以符合问题,但是我的实际上是存储数组。
Duncanmoo

3
挣扎着其他的解决方案的工作-这是如此简单,似乎真正的工作
奈特

如何删除会话变量?
siddiq

非常感谢您的工作
凯文(Kevin)

17

答案较晚,但是值得一提的是,只要临时存储库有权访问活动会话,就可以对匿名用户使用私有临时存储库。为此,您需要为类注入临时存储,会话和当前用户的服务,如下所示:

public function __construct(PrivateTempStoreFactory $temp_store_factory, SessionManagerInterface $session_manager, AccountInterface $current_user) {
    $this->tempStoreFactory = $temp_store_factory;
    $this->sessionManager = $session_manager;
    $this->currentUser = $current_user;

    $this->store = $this->tempStoreFactory->get('myclass.storename');
}

public static function create(ContainerInterface $container) {
    return new static(
        $container->get('user.private_tempstore'),
        $container->get('session_manager'),
        $container->get('current_user')
    );
}

然后,您需要确保在用户匿名的情况下启动会话管理器,然后再将任何内容放入临时存储中:

if ($this->currentUser->isAnonymous() && !isset($_SESSION['session_started'])) {
    $_SESSION['session_started'] = true;
    $this->sessionManager->start();
}

您可能会发现此方法更可取,因为这意味着您可以使用单个系统进行临时存储,而不管用户是否登录。

(我的代码示例从这个构建多步表单的出色教程中大致逐字逐句地翻译了。)


有趣的是,我会看一下,但是我喜欢这种方法
Kevin

看看如何在Drupal 8(在beta6之后)drupal.org/node/2228871中启动会话。也许我们应该修改答案中的第二个代码片段。
David Riccitelli '16


3

会话可以是匿名的(uid = 0)。您可以简单地使用$ _SESSION,而drupal会解决这个问题。

存储会话数据:

$_SESSION['mymodule']['variablename'] = $tempdata;

获取会话数据:

$tempdata = $_SESSION['mymodule']['variablename'];

更新1:会话对象

尽管D8核心仍在进行工作,请参见此问题将$ _SESSION的用法转换为从请求中检索到的symfony会话,您可以在请求中使用会话对象来存储会话数据。但是请不要将其混合使用,使用其他方法之一存储的数据将无法使用。请参阅此答案以获取更多详细信息Drupal 8和会话管理

class MymoduleSessionCounter {
  function increment(Request $request) {
    $session = $request->getSession();
    $value = $session->get('mymodule_count', 0);
    $session->set('mymodule_count', $value + 1);

    return $value;
  }
}

更新2:TempStore

TempStore在D8中似乎很受欢迎。但是存储这样的问题的值太复杂了。它适用于大块数据,例如预览数据或未保存的视图。以下是官方变更记录:

通过Request对象访问会话数据

添加了TempStore API,用于持久存储过期的非缓存数据


是的会话可以是匿名的,但对于用户服务显然不是。
凯文

在Drupal 8中,最佳实践指示您应该使用接口来读取数据并将数据写入会话变量。这样可以实现可交换存储,并拥有更光明的未来。
乔治,

1

$this->sessionManager->start();不工作了,因为上次更新的我。我将其更改为$this->sessionManager->regenerate();


您应该将此添加为原始答案的注释,而不是新答案
wranvaud

1
@wranvaud,我的声誉不足,无法评论其他答案。
Dan Poenaru
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.