Nette Documentation Preview

syntax
セッション
*****

<div class=perex>

HTTP はステートレスプロトコルですが、ほぼすべてのアプリケーションはリクエスト間で状態を維持する必要があります。例えば、ショッピングカートの内容などです。セッションはまさにこの目的のために使用されます。ここでは、

- セッションの使用方法
- 名前の衝突を回避する方法
- 有効期限の設定方法

</div>

セッションを使用する場合、各ユーザーはセッション ID と呼ばれる一意の識別子を受け取り、これはクッキーで渡されます。これはセッションデータのキーとして機能します。ブラウザ側に保存されるクッキーとは異なり、セッションデータはサーバー側に保存されます。

セッションは[設定 |configuration#セッション]で設定します。特に有効期限の選択が重要です。

セッション管理は [api:Nette\Http\Session] オブジェクトが担当します。これには、[依存性注入|dependency-injection:passing-dependencies] を使用して渡すことでアクセスできます。Presenter では、単に `$session = $this->getSession()` を呼び出すだけです。

→ [インストールと要件 |@home#インストール]


セッションの開始
========

Nette はデフォルト設定では、データの読み取りまたは書き込みを開始したときに自動的にセッションを開始します。手動でセッションを開始するには `$session->start()` を使用します。

PHP はセッションの開始時にキャッシュに影響を与える HTTP ヘッダー([php:session_cache_limiter]参照)と、場合によってはセッション ID を含むクッキーを送信します。そのため、ブラウザに何らかの出力が送信される前に常にセッションを開始する必要があります。そうしないと例外がスローされます。したがって、ページのレンダリング中にセッションが使用されることがわかっている場合は、事前に手動で開始してください。例えば Presenter で。

開発モードでは、Tracy がセッションを開始します。これは、Tracy Bar でのリダイレクトや AJAX リクエストのバーを表示するために使用するためです。


セクション
=====

純粋な PHP では、セッションデータストレージはグローバル変数 `$_SESSION` を介してアクセス可能な配列として実装されます。問題は、アプリケーションが通常、相互に独立した多数の部分で構成されており、すべてが 1 つの配列しか利用できない場合、遅かれ早かれ名前の衝突が発生することです。

Nette Framework は、スペース全体をセクション([api:Nette\Http\SessionSection] オブジェクト)に分割することでこの問題を解決します。各ユニットは一意の名前を持つ独自のセクションを使用するため、衝突は発生しません。

セッションからセクションを取得します:

```php
$section = $session->getSection('unique_name');
```

Presenter では、パラメータ付きで `getSession()` を使用するだけです:

```php
// $this は Presenter です
$section = $this->getSession('unique_name');
```

セクションの存在は `$session->hasSection('unique_name')` メソッドで確認できます。

セクション自体は、`set()`、`get()`、`remove()` メソッドを使用して非常に簡単に操作できます:

```php
// 変数の書き込み
$section->set('userName', 'john');

// 変数の読み取り、存在しない場合は null を返します
echo $section->get('userName');

// 変数の削除
$section->remove('userName');
```

セクションからすべての変数を取得するには、`foreach` ループを使用できます:

```php
foreach ($section as $key => $val) {
	echo "$key = $val";
}
```


有効期限の設定
-------

個々のセクション、または個々の変数に対して有効期限を設定できます。これにより、ユーザーのログインを 20 分後に期限切れにすることができますが、カートの内容は引き続き記憶されます。

```php
// セクションは 20 分後に期限切れになります
$section->setExpiration('20 minutes');
```

個々の変数の有効期限を設定するには、`set()` メソッドの 3 番目のパラメータを使用します:

```php
// 変数 'flash' は 30 秒後に期限切れになります
$section->set('flash', $message, '30 seconds');
```

.[note]
セッション全体の有効期限([セッション設定 |configuration#セッション]参照)は、個々のセクションまたは変数に設定された時間と同じかそれ以上でなければならないことを忘れないでください。

以前に設定された有効期限をキャンセルするには `removeExpiration()` メソッドを使用します。セクション全体を即座にキャンセルするには `remove()` メソッドを使用します。


イベント $onStart, $onBeforeWrite
-----------------------------

`Nette\Http\Session` オブジェクトには[イベント |nette:glossary#イベント] `$onStart` と `$onBeforeWrite` があります。したがって、セッションの開始後またはディスクへの書き込みとそれに続く終了前に呼び出されるコールバックを追加できます。

```php
$session->onBeforeWrite[] = function () {
	// セッションにデータを書き込みます
	$this->section->set('basket', $this->basket);
};
```


セッション管理
=======

セッション管理のための `Nette\Http\Session` クラスのメソッドの概要:

<div class=wiki-methods-brief>


start(): void .[method]
-----------------------
セッションを開始します。


isStarted(): bool .[method]
---------------------------
セッションは開始されていますか?


close(): void .[method]
-----------------------
セッションを終了します。セッションはスクリプトの実行終了時に自動的に終了します。


destroy(): void .[method]
-------------------------
セッションを終了して削除します。


exists(): bool .[method]
------------------------
HTTP リクエストにセッション ID を含むクッキーが含まれていますか?


regenerateId(): void .[method]
------------------------------
新しいランダムなセッション ID を生成します。データは保持されます。


getId(): string .[method]
-------------------------
セッション ID を返します。

</div>


設定
-----------

セッションは[設定 |configuration#セッション]で設定します。DI コンテナを使用しないアプリケーションを作成している場合は、これらのメソッドを使用して設定します。これらはセッションを開始する前に呼び出す必要があります。

<div class=wiki-methods-brief>


setName(string $name): static .[method]
---------------------------------------
セッション ID が転送されるクッキーの名前を設定します。標準の名前は `PHPSESSID` です。これは、1 つのウェブサイト内で複数の異なるアプリケーションを運用する場合に便利です。


getName(): string .[method]
---------------------------
セッション ID が転送されるクッキーの名前を返します。


setOptions(array $options): static .[method]
--------------------------------------------
セッションを設定します。すべての PHP [セッションディレクティブ|https://www.php.net/manual/en/session.configuration.php](camelCase 形式、例:`session.save_path` の代わりに `savePath` と記述)と [readAndClose |https://www.php.net/manual/en/function.session-start.php#refsect1-function.session-start-parameters] を設定できます。


setExpiration(?string $time): static .[method]
----------------------------------------------
セッションが期限切れになるまでの非アクティブ期間を設定します。


setCookieParameters(string $path, ?string $domain=null, ?bool $secure=null, ?string $samesite=null): static .[method]
---------------------------------------------------------------------------------------------------------------------
クッキーのパラメータを設定します。パラメータのデフォルト値は[設定 |configuration#セッションクッキー]で変更できます。


setSavePath(string $path): static .[method]
-------------------------------------------
セッションファイルが保存されるディレクトリを設定します。


setHandler(\SessionHandlerInterface $handler): static .[method]
---------------------------------------------------------------
カスタムハンドラを設定します。[PHP ドキュメント|https://www.php.net/manual/en/class.sessionhandlerinterface.php]を参照してください。

</div>


セキュリティ第一
========

サーバーは、リクエストが同じセッション ID を伴う限り、常に同じユーザーと通信していると想定します。セキュリティメカニズムのタスクは、これが実際にそうであり、識別子を盗んだり偽装したりできないことを保証することです。

したがって、Nette Framework は PHP ディレクティブを正しく設定し、セッション ID をクッキーでのみ転送し、JavaScript からアクセスできないようにし、URL 内の識別子を無視します。さらに、ユーザーのログインなどの重要な瞬間には、新しいセッション ID を生成します。

.[note]
PHP の設定には ini_set 関数が使用されますが、残念ながら一部のホスティングプロバイダーはこの関数を禁止しています。これがあなたのホスティングプロバイダーの場合、関数を有効にするか、少なくともサーバーを設定するように交渉してみてください。

セッション

HTTP はステートレスプロトコルですが、ほぼすべてのアプリケーションはリクエスト間で状態を維持する必要があります。例えば、ショッピングカートの内容などです。セッションはまさにこの目的のために使用されます。ここでは、

  • セッションの使用方法
  • 名前の衝突を回避する方法
  • 有効期限の設定方法

セッションを使用する場合、各ユーザーはセッション ID と呼ばれる一意の識別子を受け取り、これはクッキーで渡されます。これはセッションデータのキーとして機能します。ブラウザ側に保存されるクッキーとは異なり、セッションデータはサーバー側に保存されます。

セッションは設定で設定します。特に有効期限の選択が重要です。

セッション管理は Nette\Http\Session オブジェクトが担当します。これには、依存性注入 を使用して渡すことでアクセスできます。Presenter では、単に $session = $this->getSession() を呼び出すだけです。

インストールと要件

セッションの開始

Nette はデフォルト設定では、データの読み取りまたは書き込みを開始したときに自動的にセッションを開始します。手動でセッションを開始するには $session->start() を使用します。

PHP はセッションの開始時にキャッシュに影響を与える HTTP ヘッダー(session_cache_limiter参照)と、場合によってはセッション ID を含むクッキーを送信します。そのため、ブラウザに何らかの出力が送信される前に常にセッションを開始する必要があります。そうしないと例外がスローされます。したがって、ページのレンダリング中にセッションが使用されることがわかっている場合は、事前に手動で開始してください。例えば Presenter で。

開発モードでは、Tracy がセッションを開始します。これは、Tracy Bar でのリダイレクトや AJAX リクエストのバーを表示するために使用するためです。

セクション

純粋な PHP では、セッションデータストレージはグローバル変数 $_SESSION を介してアクセス可能な配列として実装されます。問題は、アプリケーションが通常、相互に独立した多数の部分で構成されており、すべてが 1 つの配列しか利用できない場合、遅かれ早かれ名前の衝突が発生することです。

Nette Framework は、スペース全体をセクション(Nette\Http\SessionSection オブジェクト)に分割することでこの問題を解決します。各ユニットは一意の名前を持つ独自のセクションを使用するため、衝突は発生しません。

セッションからセクションを取得します:

$section = $session->getSection('unique_name');

Presenter では、パラメータ付きで getSession() を使用するだけです:

// $this は Presenter です
$section = $this->getSession('unique_name');

セクションの存在は $session->hasSection('unique_name') メソッドで確認できます。

セクション自体は、set()get()remove() メソッドを使用して非常に簡単に操作できます:

// 変数の書き込み
$section->set('userName', 'john');

// 変数の読み取り、存在しない場合は null を返します
echo $section->get('userName');

// 変数の削除
$section->remove('userName');

セクションからすべての変数を取得するには、foreach ループを使用できます:

foreach ($section as $key => $val) {
	echo "$key = $val";
}

有効期限の設定

個々のセクション、または個々の変数に対して有効期限を設定できます。これにより、ユーザーのログインを 20 分後に期限切れにすることができますが、カートの内容は引き続き記憶されます。

// セクションは 20 分後に期限切れになります
$section->setExpiration('20 minutes');

個々の変数の有効期限を設定するには、set() メソッドの 3 番目のパラメータを使用します:

// 変数 'flash' は 30 秒後に期限切れになります
$section->set('flash', $message, '30 seconds');

セッション全体の有効期限(セッション設定参照)は、個々のセクションまたは変数に設定された時間と同じかそれ以上でなければならないことを忘れないでください。

以前に設定された有効期限をキャンセルするには removeExpiration() メソッドを使用します。セクション全体を即座にキャンセルするには remove() メソッドを使用します。

イベント $onStart, $onBeforeWrite

Nette\Http\Session オブジェクトにはイベント $onStart$onBeforeWrite があります。したがって、セッションの開始後またはディスクへの書き込みとそれに続く終了前に呼び出されるコールバックを追加できます。

$session->onBeforeWrite[] = function () {
	// セッションにデータを書き込みます
	$this->section->set('basket', $this->basket);
};

セッション管理

セッション管理のための Nette\Http\Session クラスのメソッドの概要:

start(): void

セッションを開始します。

isStarted(): bool

セッションは開始されていますか?

close(): void

セッションを終了します。セッションはスクリプトの実行終了時に自動的に終了します。

destroy(): void

セッションを終了して削除します。

exists(): bool

HTTP リクエストにセッション ID を含むクッキーが含まれていますか?

regenerateId(): void

新しいランダムなセッション ID を生成します。データは保持されます。

getId(): string

セッション ID を返します。

設定

セッションは設定で設定します。DI コンテナを使用しないアプリケーションを作成している場合は、これらのメソッドを使用して設定します。これらはセッションを開始する前に呼び出す必要があります。

setName(string $name): static

セッション ID が転送されるクッキーの名前を設定します。標準の名前は PHPSESSID です。これは、1 つのウェブサイト内で複数の異なるアプリケーションを運用する場合に便利です。

getName(): string

セッション ID が転送されるクッキーの名前を返します。

setOptions(array $options)static

セッションを設定します。すべての PHP セッションディレクティブ(camelCase 形式、例:session.save_path の代わりに savePath と記述)と readAndClose を設定できます。

setExpiration(?string $time)static

セッションが期限切れになるまでの非アクティブ期間を設定します。

setCookieParameters(string $path, ?string $domain=null, ?bool $secure=null, ?string $samesite=null)static

クッキーのパラメータを設定します。パラメータのデフォルト値は設定で変更できます。

setSavePath(string $path)static

セッションファイルが保存されるディレクトリを設定します。

setHandler(\SessionHandlerInterface $handler)static

カスタムハンドラを設定します。PHP ドキュメントを参照してください。

セキュリティ第一

サーバーは、リクエストが同じセッション ID を伴う限り、常に同じユーザーと通信していると想定します。セキュリティメカニズムのタスクは、これが実際にそうであり、識別子を盗んだり偽装したりできないことを保証することです。

したがって、Nette Framework は PHP ディレクティブを正しく設定し、セッション ID をクッキーでのみ転送し、JavaScript からアクセスできないようにし、URL 内の識別子を無視します。さらに、ユーザーのログインなどの重要な瞬間には、新しいセッション ID を生成します。

PHP の設定には ini_set 関数が使用されますが、残念ながら一部のホスティングプロバイダーはこの関数を禁止しています。これがあなたのホスティングプロバイダーの場合、関数を有効にするか、少なくともサーバーを設定するように交渉してみてください。