セッション
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 オブジェクト)に分割することでこの問題を解決します。各ユニットは一意の名前を持つ独自のセクションを使用するため、衝突は発生しません。
セッションからセクションを取得します:
Presenter では、パラメータ付きで getSession()
を使用するだけです:
セクションの存在は $session->hasSection('unique_name')
メソッドで確認できます。
セクション自体は、set()
、get()
、remove()
メソッドを使用して非常に簡単に操作できます:
セクションからすべての変数を取得するには、foreach
ループを使用できます:
有効期限の設定
個々のセクション、または個々の変数に対して有効期限を設定できます。これにより、ユーザーのログインを 20 分後に期限切れにすることができますが、カートの内容は引き続き記憶されます。
個々の変数の有効期限を設定するには、set()
メソッドの 3
番目のパラメータを使用します:
セッション全体の有効期限(セッション設定参照)は、個々のセクションまたは変数に設定された時間と同じかそれ以上でなければならないことを忘れないでください。
以前に設定された有効期限をキャンセルするには removeExpiration()
メソッドを使用します。セクション全体を即座にキャンセルするには remove()
メソッドを使用します。
イベント $onStart, $onBeforeWrite
Nette\Http\Session
オブジェクトにはイベント $onStart
と $onBeforeWrite
があります。したがって、セッションの開始後またはディスクへの書き込みとそれに続く終了前に呼び出されるコールバックを追加できます。
セッション管理
セッション管理のための 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 関数が使用されますが、残念ながら一部のホスティングプロバイダーはこの関数を禁止しています。これがあなたのホスティングプロバイダーの場合、関数を有効にするか、少なくともサーバーを設定するように交渉してみてください。