フォームを送信し、送信した値をセッションに保存したい。 Drupal 7では、私は$_SESSION['key'] = $value;
しかし、Drupal 8でこれを正しく実装するにはどうすればよいですか?
Drupal 8はSymfonyの HttpFoundationセッション管理 を使用するため、APIがドキュメント化されています。
core.services.yml
Drupalのラッパーが入っていることがわかります。
session_manager:
class: Drupal\Core\Session\SessionManager
D8では、セッションデータはリクエストに添付されたsymfonyセッションオブジェクトによって提供されます。 D7とD8の次の比較を参照してください。
Drupal 7:
_function mymodule_session_counter_increment() {
if (!isset($_SESSION['mymodule_count'])) {
$_SESSION['mymodule_count'] = 0;
}
return $_SESSION['mymodule_count']++;
}
_
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;
}
}
_
変更レコード: Requestオブジェクトを介してセッションデータにアクセス
セッション管理は変更されていません。 Drupalは各リクエストのセッションを自動的に開始し、すぐに使用できるため、何もする必要はありません。
セッションの取得方法の例:
手続き型
手続き型コードでは、静的ラッパー_\Drupal
_からリクエストを取得します。
_$request = \Drupal::request();
$session = $request->getSession();
$session->set('mymodule_value', $value);
_
コントローラー
コントローラーでは、型指定された要求パラメーターを含めることにより、ルート引数スタックから要求をプルできます。 UserController
の例:
_ public function resetPass(Request $request, $uid, $timestamp, $hash) {
...
$session = $request->getSession();
$session->set('pass_reset_hash', $hash);
$session->set('pass_reset_timeout', $timestamp);
...
}
_
ルート定義でルートパラメータを定義する必要はありません。リクエストは常に利用可能です。
フォーム
フォームメソッドでgetRequest()
からリクエストを取得します。
_ public function submitForm(array &$form, FormStateInterface $form_state) {
$session = $this->getRequest()->getSession();
$session->set('mymodule_form_value', $form_state->getValue('value'));
}
_
プライベートテンプストア
プライベートtempstoreはセッションの代わりにはなりません。これはセッションIDに依存し、セッションなしでは使用できません。したがって、値をセッションに直接保存することもできます。 Drupalコアは、大量のデータのために、すでにセッションを持っている認証済みユーザーに対してのみ、プライベート一時ストアを使用します。匿名ユーザーの場合、プライベート一時ストアを開始するのは簡単ではありません。drupalは、実際のセッションを開始するまでダミーのセッションIDを使用します。カスタムコードでプライベートテンポストアを開始すると、セッションIDが間違っています。
適切なサービスを使用してセッションにデータを保存する方法に関する記事は次のとおりです。 http://atendesigngroup.com/blog/storing-session-data-drupal-8
この記事では2つの方法について説明していますが、ここでは依存性注入を使用しない最初の方法を示します。 (コードは私のものではありません)
一時データを設定するには:
// For "mymodule_name," any unique namespace will do.
// I'd probably use "mymodule_name" most of the time.
$tempstore = \Drupal::service('user.private_tempstore')->get('mymodule_name');
$tempstore->set('my_variable_name', $some_data);
一時データを読み取るには:
$tempstore = \Drupal::service('user.private_tempstore')->get('mymodule_name');
$some_data = $tempstore->get('my_variable_name');
セッションにデータを一時的に保存するには、Drupal 8.5以降には tempstore.privateがあります) たとえば、ノードプレビューフォームを一時的に保存するためにノード編集フォームから使用されるサービス。
public function form(array $form, FormStateInterface $form_state) {
// Try to restore from temp store, this must be done before calling
// parent::form().
$store = $this->tempStoreFactory
->get('node_preview');
// Attempt to load from preview when the uuid is present unless we are
// rebuilding the form.
$request_uuid = \Drupal::request()->query
->get('uuid');
if (!$form_state
->isRebuilding() && $request_uuid && ($preview = $store
->get($request_uuid))) {
/** @var $preview \Drupal\Core\Form\FormStateInterface */
$form_state
->setStorage($preview
->getStorage());
$form_state
->setUserInput($preview
->getUserInput());
// Rebuild the form.
$form_state
->setRebuild();
// The combination of having user input and rebuilding the form means
// that it will attempt to cache the form state which will fail if it is
// a GET request.
$form_state
->setRequestMethod('POST');
$this->entity = $preview
->getFormObject()
->getEntity();
$this->entity->in_preview = NULL;
$form_state
->set('has_been_previewed', TRUE);
}
/** @var \Drupal\node\NodeInterface $node */
$node = $this->entity;
if ($this->operation == 'edit') {
$form['#title'] = $this
->t('<em>Edit @type</em> @title', [
'@type' => node_get_type_label($node),
'@title' => $node
->label(),
]);
}
// ...
}
/**
* Form submission handler for the 'preview' action.
*
* @param $form
* An associative array containing the structure of the form.
* @param $form_state
* The current state of the form.
*/
public function preview(array $form, FormStateInterface $form_state) {
$store = $this->tempStoreFactory
->get('node_preview');
$this->entity->in_preview = TRUE;
$store
->set($this->entity
->uuid(), $form_state);
$route_parameters = [
'node_preview' => $this->entity
->uuid(),
'view_mode_id' => 'full',
];
$options = [];
$query = $this
->getRequest()->query;
if ($query
->has('destination')) {
$options['query']['destination'] = $query
->get('destination');
$query
->remove('destination');
}
$form_state
->setRedirect('entity.node.preview', $route_parameters, $options);
}
Drupal 8.5より前の場合、サービスは user.private_tempstore であり、次の場所で削除されますDrupal 9.0。
送信された値を保存したいので、これは限られた期間のみ使用され、ユーザーがログインまたはログアウトした後は不要になると想定しているため、Drupalコアは、ノードが作成/保存される前にノードのプレビューを表示します。また、データの削除が自動的に行われるという長所もあります。
自分でロールする前に、 Session Node Access モジュールが必要なことを行っているかどうかを確認してください。
セッション(Drupal 8)は、SessionInterfaceインターフェースの単純なセッション実装を介して使用されます。
SymfonyセッションはいくつかのネイティブPHP関数を置き換えるように設計されています。アプリケーションはsession_start()、session_regenerate_id()、session_id()、session_name()、およびsession_destroy()の使用を避け、代わりにAPIを使用する必要があります次のセクション。
例:
use Symfony\Component\HttpFoundation\Session\Session;
$session = new Session();
$session->start();
// set and get session attributes
$session->set('name', 'Yash');
$session->get('name');
// set flash messages
$session->getFlashBag()->add('notice', 'Profile updated');
// retrieve messages
foreach ($session->getFlashBag()->get('notice', array()) as $message) {
echo '<div class="flash-notice">'.$message.'</div>';
}
「\ Drupal :: service()」を使用できます。
一時データを設定するには:
$tempstore = \Drupal::service('user.private_tempstore')->get('mymodule_name');
$tempstore->set('my_variable_name', $some_data);
一時データを読み取るには:
$tempstore = \Drupal::service('user.private_tempstore')->get('mymodule_name');
$some_data = $tempstore->get('my_variable_name');
詳細は このチュートリアル を参照してください。
どうですか? :
$session = new Session();
$session->set('key', 'value');
$key= $session->get("key");
var_dump($key);