ホームページ  >  記事  >  バックエンド開発  >  PHP でのセッションのライフサイクル

PHP でのセッションのライフサイクル

WBOY
WBOYオリジナル
2016-06-23 13:25:341019ブラウズ

まず、セッション作成の開始から終了までのプロセスについて説明します。

プログラムがクライアントのリクエストに対してセッションを作成する必要がある場合、サーバーはまずクライアントにセッション ID と呼ばれるセッション識別子が既に含まれているかどうかを確認します (セッションが既に含まれている場合、取得メソッドは session_id() です)。 id は、クライアントが以前にセッションを作成したことがあり、サーバーがセッション ID に従ってセッション内の値を取得することを意味します。クライアントにセッション ID が含まれていない場合は、クライアントが初めてサーバーを要求したことを意味します。キャッシュ ファイルを手動でクリアした場合、このクライアントのセッションを作成し、このセッションに関連付けられたセッション ID を生成します。一般的に、セッション ID の値は繰り返されず、暗号化された文字列であるこのセッション ID が使用されます。応答は保管のためにクライアントに返されます。

セッションはいつ作成されますか?

通常(通常という意味)ブラウザがサーバーに最初のリクエストを行うときに作成され、ある程度のメモリスペースを占有するため、不要な場合はセッションを閉じるようにしてください。

セッションはいつ削除されますか?

通常、セッションは次の状況で削除されます:

まず、session_destroy() リセット関数を使用して手動で削除します。

次に、セッションの最後のアクティビティ時刻と現在の時刻の間の間隔が時間を超えます。セッション タイムアウト設定 3 つ目は、サーバー プロセスを停止することです。

ブラウザを閉じたときにセッションを削除するにはどうすればよいですか?

理論的には、これは不可能です。http はステートレス プロトコルであるため、サーバーはクライアントがいつブラウザを閉じたかを知りません。また、PHP にはこの情報を取得するための関連機能がありません。しかし、この問題はまだ解決できます。つまり、Web ページの特殊効果コード window.oncolose を使用してブラウザの終了アクションを監視し、Ajax を使用してサーバーにセッションを削除するリクエストを送信します。ただし、この方法では問題が完全に解決されません。ブラウザのクラッシュ、突然の停電、ユーザーのフリーズなど、場合によっては対応できない場合がございます。

一定期間後にセッションが自動的に期限切れになる (削除される) ように設定するにはどうすればよいですか?

session_start() はセッションメカニズムの始まりであり、一定の確率でガベージコレクションを有効にします。セッションはファイルに保存されるため、SESSION のリサイクル (削除) は無効になります。この確率は php.ini の設定に基づいて決定されますが、一部のシステムでは session.gc_probability = 0 が設定されており、これは確率が 0 であることを意味し、ガベージ コレクション (つまり、セッションの削除) は cron スクリプトを通じて実装されます。 。

PHP のデフォルトのセッション有効期間は 1440 秒 (24 分、注意: php5 のデフォルトは 180 分)、つまり、クライアントが 24 分を超えて更新しない場合、現在のセッションは期限切れになります。明らかに、これは実行できません。

既知の効果的な方法は、session_set_save_handler を使用してすべてのセッション管理作業を引き継ぐことです。これにより、期限切れのセッションはすべて SQL ステートメントを通じて削除できます。これは、PHP をベースにした大規模な Web サイトでは一般的な方法ですが、一般的なセッションにはその必要はないようです。有効期間は限られており、ユーザーがブラウザを閉じるとセッション変数は保存されません。それでは、どうすればセッションの永続的な有効期間を実現できるのでしょうか? ご存知のとおり、セッションはサーバー側に保存され、ユーザーのファイルは保存されます。クライアントから提供されたSessionIDに基づいてファイルが読み取られ、変数SessionIDの値が取得されます。クライアントのCookieまたはHttp1.1プロトコルのQuery_String(アクセスされた文字列の「?」以降の部分)を使用できます。 URL) を使用してサーバーに送信すると、サーバーはセッション ディレクトリを読み取ります

セッションの永続的な存続期間を理解するには、まずセッションに関する php.ini の関連設定を見てみましょう ( php.ini ファイルの「[Session]」セクションを開きます):

1. session.use_cookies: デフォルト値は「1」で、SessionID が Cookie によって渡され、その逆も同様です。 ;

2. session.name: これは、SessionID に保存される変数名です。デフォルト値は、「PHPSESSID」です。

3. これは、デフォルトの保存時間を表します。クライアント Cookie の値は 0 です。これは、ブラウザを閉じるとすぐにセッション ID が無効になることを意味します。このため、セッションは永続的に使用できなくなります。

4. これが時間です。この時間を超えると、セッション データは自動的に削除されます。

この記事に関連する設定は次のとおりです。永続的なセッションの使用方法

前に述べたように、サーバーはセッション データを読み取るためにセッション ID を渡しますが、通常、ブラウザから送信されたセッション ID はブラウザを閉じると失われるため、手動でセッション ID を設定して保存するだけで済みます。それ、それです。サーバーの操作権限を持っている場合、次の手順に従うだけで、セットアップは非常に簡単です。

1. "session.use_cookies" を 1 に設定し、セッション ID を保存するための Cookie をオンにします。ただし、デフォルトは 1 です。通常は変更する必要はありません。

2. "session.cookie_lifetime" を正の無限大に変更します。正の無限大パラメータですが、999999999 と正の無限大の間に違いはありません);

3. 「session.gc_maxlifetime」を「session.cookie_lifetime」と同じ時間に設定します

このパラメータは、PHP ドキュメントに明記されています。セッションの有効期間を設定するのは gc_maxlifetime です。このパラメータは、php.ini ファイルまたは ini_set() 関数を通じて変更できます。問題は、多くのテストを行った後、このパラメーターを変更しても基本的には効果がなく、セッションの有効期間がデフォルト値の 24 分のままであることです。

PHP の動作メカニズムにより、セッション情報を定期的にスキャンして、セッション情報が無効かどうかを判断するデーモン スレッドがありません。有効なリクエストが発生すると、PHP はグローバル変数 session.gc_probability/session.gc_divisor (php.ini または ini_set() 関数を通じて変更することもできます) の値に基づいて GC (ガベージ コレクター) を開始するかどうかを決定します。 。

デフォルトでは、session.gc_probability = 1、session.gc_divisor = 100 です。これは、GC が開始される確率が 1% であることを意味します。 GC の役割は、すべてのセッション情報をスキャンし、現在の時刻からセッションの最終変更時刻 (変更日) を減算し、それを session.gc_maxlifetime パラメータと比較することです。生存時間が gc_maxlifetime を超えている場合は、セッションを削除します。

これまでのところ、すべてがうまく機能しています。では、なぜ gc_maxlifetime が無効になるのでしょうか?

デフォルトでは、セッション情報はシステムの一時ファイル ディレクトリにテキスト ファイルの形式で保存されます。 Linux では、このパスは通常 tmp であり、Windows では通常 C:WindowsTemp です。サーバー上に複数の PHP アプリケーションがある場合、それらのセッション ファイルは同じディレクトリに保存されます。同様に、これらの PHP アプリケーションも一定の確率で GC を開始し、すべてのセッション ファイルをスキャンします。

問題は、GC が動作しているときに、異なるサイト上のセッションが区別されないことです。たとえば、サイト A の gc_maxlifetime は 2 時間に設定され、サイト B の gc_maxlifetime はデフォルトの 24 分に設定されます。サイト B の GC が開始されると、パブリック一時ファイル ディレクトリがスキャンされ、サイト A からのものかサイト B からのものかに関係なく、24 分より古いすべてのセッション ファイルが削除されます。このように、サイト A の gc_maxlifetime 設定は役に立ちません。

問題を見つけたら、解決するのは簡単です。 session.save_path パラメータを変更するか、session_save_path() 関数を使用して、セッションが保存されるディレクトリを専用のディレクトリに指定します。 gc_maxlifetime パラメータは正常に機能します。

厳密に言うと、これは PHP のバグですか?

もう 1 つの問題は、gc_maxlifetime が保証できるのはセッションの存続時間の最短時間だけであり、この時間を過ぎるとセッション情報はすぐに削除されることです。 GC は確率に基づいて開始され、長期間開始されない可能性があるため、gc_maxlifetime を超えた後も多数のセッションが有効になります。

この問題を解決する 1 つの方法は、session.gc_probability/session.gc_divisor の確率を 100% まで高めることです。ただし、この問題は明らかにパフォーマンスに重大な影響を及ぼします。もう 1 つの方法は、コード内で現在のセッションの存続期間を確認し、それが gc_maxlifetime を超えた場合は、現在のセッションをクリアすることです。

ただし、サーバーを操作する権限がない場合、永続的なセッションデータの保存を実現するには、PHP プログラムを通じて SessionID を書き換える必要があります。 php.net の関数マニュアルを確認すると、「session_id」関数が表示されます。パラメータが設定されていない場合は、現在の SessionID が返されます。パラメータが設定されている場合、現在の SessionID は指定された値に設定されます。

永続的な Cookie を使用し、「session_id」関数を追加する限り、永続的なセッション データを保存できます。

ただし、便宜上、サーバー設定の "session.name" を知る必要がありますが、一般のユーザーにはサーバーの php.ini 設定を表示する権限はありませんが、PHP には非常に優れた関数 "phpinfo" が用意されています。ほぼすべての PHP 情報を表示するために使用されます。

<?phpphpinfo();

エディタを開いて上記のコードを入力し、ブラウザでプログラムを実行すると、PHP 関連の情報が表示されます。 「session.name」パラメータがあります。これは必要なサーバーの「session.name」で、通常は「PHPSESSID」です。

SessionID の名前を書き留めると、永続的なセッション データ ストレージを実現できます。

<?phpsession_start();ini_set('session.save_path','/tmp/');//6个钟头ini_set('session.gc_maxlifetime',21600);//保存一天$lifeTime = 24 * 3600;setcookie(session_name(), session_id(), time() + $lifeTime, "/");

さらに、php セッションの生存時間を設定するために、ネットユーザーがインターネット上で非常に優れた方法を書いているのを見つけました。ここでコードを共有します:

<?phpfunction start_session($expire=0){	if($expire==0){		$expire=ini_get('session.gc_maxlifetime');	}else{		ini_set('session.gc_maxlifetime',$expire);	}	if(empty($_COOKIE['PHPSESSID'])){		session_set_cookie_params($expire);		session_start();	}else{		session_start();		setcookie('PHPSESSID',session_id(),time()+$expire);	}}

使用方法も非常に簡単です。たとえば、次のとおりです。

<?php start_session(600);//600秒以后过期

追記: 実際、Cookie の保存時間は限られており、サーバーの容量も限られているため、本当の永久保存は不可能です...しかし、長期間保存する必要がある一部のサイトでは、上記の方法で十分です!

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。