ホームページ  >  記事  >  バックエンド開発  >  PHPセッション処理

PHPセッション処理

z老师
z老师オリジナル
2016-06-23 14:34:401156ブラウズ

PHPセッション処理

セッションは2つの部分に分かれており、セッションスペースはサーバー側に保存され、オープンスペースのIDはクライアントのCookieに保存されます。クライアントがCookieを閉じると、セッションは正常に使用できなくなります。

セッションの中国語訳は「会話」といい、本来の意味は始まりと終わりのある一連の行為・メッセージを指します。例えば、電話をかけるとき、受話器を取るまでの一連のプロセスを指します。ダイヤルして電話を切ることをセッションと呼ぶことができます。現在の社会におけるセッションの理解は非常に混乱しています。「ブラウザ セッション中、...」のような言葉が時々見られます

ここでのセッションとは、ブラウザ ウィンドウが開いてから閉じるまでの期間を指します。 「セッション中のユーザー(クライアント)」という文言を見ると、それはユーザーの一連の行動(一般的には、ログインから商品の購入、チェックアウトまでなど、特定の目的に関連する一連の行動)を指す場合があります。ただし、このようなオンライン ショッピング プロセスからのログアウトは、接続のみを指す場合があります。その違いはコンテキストからのみ推測できます

関連トピックの推奨事項 (画像、テキスト、ビデオを含む)ただし、セッションという言葉がネットワーク プロトコルに関連付けられている場合、多くの場合、「接続指向」および/または「状態の維持」という 2 つの意味が含まれます。「接続指向」とは、通信する前の通信を指します。相手が電話をかけるなど、最初に通信チャネルを確立する必要があります。「ステータスの維持」とは、通信相手が一連のメッセージを関連付けて、それぞれのメッセージを通信できるようにすることを意味します。その他。依存性。たとえば、ウェイターは、再び来た古い顧客を認識し、その顧客が前回店に 1 ドルを借りていたことを思い出すことができます。このタイプの例としては、「TCP セッション」または「POP3 セッション」があります。この混乱は変更できず、セッションを定義するための統一した基準を持つことは困難です。たとえば、電話をかける場合など、セッションに関する関連情報を読むときは、文脈から推測することによってのみ理解できます。通話が切れた瞬間から、通話は接続されたままになるため、この接続状態はセッションと呼ばれ、訪問者と Web サイト全体との間の対話中に常に存在し、存在しません。クライアント上で COOKIE がサポートされている場合、Web サイトを訪問する訪問者には、クライアントの Cookie に保存されるか、URL を通じて渡される一意の識別子、いわゆるセッション ID が割り当てられます。 SESSION の発明は、HTTP プロトコルの制限を補います。HTTP プロトコルはステートレス プロトコルと見なされ、サーバー側で応答が完了すると、サーバーはブラウザとの接続を失います。 HTTP プロトコルの目的は一貫しています。クライアントはサーバーに特定のファイルをダウンロードするよう要求するだけで済みます。顧客とサーバー間の関係と同様に、クライアントもサーバーもお互いの過去の行動を記録する必要はありません。自動販売機や通常の(非会員制)ハイパーマーケットでも同じです。したがって、ユーザーがこの ID を再度使用するために、ユーザーの関連情報が SESSION を通じて記録されます。 Web サーバーの発明により、ユーザーは複数のページを切り替えるときに自分の情報を保存できます。ウェブサイトのプログラマーなら誰しも経験があると思いますが、各ページの変数は次のページでは使用できません(フォームやURLも実装できますが、非常に不十分な方法です)。一方、SESSIONに登録された変数はグローバルとして使用できます。変数。

それでは、SESSION の用途は何でしょうか?

オンラインで買い物をするとき、誰もがショッピング カートを使用したことがあります。いつでも選択した商品をショッピング カートに追加し、最後にチェックアウト カウンターに行って会計を行うことができます。プロセス全体を通じて、ショッピング カートは選択した商品を一時的に保存する役割を果たします。これは、ユーザーの ID 認証やプログラムのステータスを追跡するために使用されます。記録、ページ間のパラメータの受け渡しなど。

Session は

を使用して実装されます。SESSION はクライアント側に session_id (SESSION 番号) を含む COOKIE を保存し、session_name などの他のセッション変数をサーバー側に保存します。

ユーザーがサーバーにリクエストすると、session_idもサーバーに送信され、session_idを通じてサーバー側に保存されている変数を抽出することで、ユーザーが誰であるかを識別できます。同時に、SESSION が時々失敗する理由を理解するのは難しくありません。

クライアントがCOOKIEを無効にしている場合(IEの「ツール」→「インターネットオプション」をクリックし、ポップアップダイアログボックスの「セキュリティ」→「レベルのカスタマイズ」をクリックし、「会話ごとにCOOKIEを許可」を「無効」に設定) , session_id は渡されず、SESSION は無効になります。ただし、php5 は Linux/Unix プラットフォーム上の Cookie ステータスを自動的にチェックできます。クライアントが無効になっている場合、システムは自動的に session_id を URL に追加して渡します。 Windows ホストにはこの機能はありません。

セッションの共通機能と使い方?

Session_start():セッションを開始するか、既存のセッションを返します。 Session_start() :开始一个会话或者返回已经存在的会话。

说明:这个函数没有参数,且返回值均为true。如果你使用基于cookie的session(cookie-based sessions),那么在使用Session_start()之前浏览器不能有任何输出,否则会发生以下错误:

Warning: Cannot send session cache limiter - headers already sent (output started at /usr/local/apache/htdocs/cga/member/1.php:2)…………

你可以在php.ini里启动session.auto_start=1,这样就无需每次使用session之前都要调用session_start()。但启用该选项也有一些限制,如果确实启用了 session.auto_start,则不能将对象放入会话中,因为类定义必须在启动会话之前加载以在会话中重建对象。

请求结束后所有注册的变量都会被序列化。已注册但未定义的变量被标记为未定义。在之后的访问中这些变量也未被会话模块定义,除非用户以后定义它们。

警告: 有些类型的数据不能被序列化因此也就不能保存在会话中。包括 resource 变量或者有循环引用的对象(即某对象将一个指向自己的引用传递给另一个对象)。

注册SESSION变量:

PHP5使用$_SESSION[‘xxx’]=xxx注册SESSION全局变量,和GET,POST,COOKIE的使用方法相似。

注意:session_register()session_unregistersession_is_registered在php5下不再使用,除非在php.ini里把register_globle设为on,不过出于安全考虑,强烈建议关闭register_globleHTTP_SESSION_VARS也不提倡使用了,官方建议用$_SESSION代替之。

例如:

Page1.php 

<?php Session_start(); //使用SESSION前必须调用该函数。
$_SESSION[‘name’]=”我是黑旋风李逵!”;
//注册一个SESSION变量 $_SESSION[‘passwd’]=”mynameislikui”;
$_SESSION[‘time’]=time();
echo '<br /><a href="page2.php">通过COOKIE传递SESSION</a>';
//如果客户端支持cookie,可通过该链接传递session到下一页。
echo '<br /><a href="page2.php?' . SID . '">通过URL传递SESSION</a>';
//客户端不支持cookie时,使用该办法传递session. ?>
Page2.php <?php session_start(); echo $_SESSION['name'];
// echo $_SESSION['passwd'];
// echo date('Y m d H:i:s', $_SESSION['time']);
echo '<br /><a href="page1.php">返回山一页</a>'; ?>

有两种方法传递一个会话 ID: cookie URL 参数

会话模块支持这两种方法。cookie 更优化,但由于不总是可用,也提供替代的方法。第二种方法直接将会话 ID 嵌入到 URL 中间去。 PHP 可以透明地转换连接。除非是使用 PHP 4.2 或更新版本,需要手工在编译 PHP 时激活。在 Unix 下,用 --enable-trans-sid 配置选项。如果此配置选项和运行时选项 session.use_trans_sid 都被激活(修改php.ini),相对 URI 将被自动修改为包含会话 ID。

session_id session_id() 用于设定或取得当前session_id。

php5中既可以使用session_id(),也可以通过附加在url上的SID取得当前会话的session_id和session_name。

如果session_id()有具体指定值的话,将取代当前的session_id值。使用该函数前必须启动会话:session_start(); 当我们使用session cookies时,如果指定了一个session_id()值,每次启动session_start()都会往客户端发送一个cookie值。不论当前 session_id是否与指定值相等。

session_id()如果没有指定值,则返回当前session_id();当前会话没有启动的话,则返回空字符串。

● 检查session是否存在?

在以往的php版本中通常使用session_is_register()检查session是否存在,如果您使用$_SESSION[‘XXX’]=XXX来注册会话变量,则session_is_register()函数不再起作用。你可以使用 isset($_SESSION[‘xxx’])来替代。

● 更改session_id session_regenerate_id() 更改成功则返回true,失败则返回false。

使用该函数可以为当前session更改session_id,但不改变当前session的其他信息。

例如:

<?php
session_start();
$old_sessionid = session_id();
session_regenerate_id();
$new_sessionid = session_id();
echo "原始 SessionID: $old_sessionid<br />";
echo "新的 SessionID: $new_sessionid<br />";
echo"<pre>"; print_r($_SESSION);
echo"</pre>";
?>

● session_name() 

返回当前session的name或改变当前session的name。

如果要改变当前session的name,必须在session_start()之前调用该函数。

注意:session_name不能只由数字组成,它至少包含一个字母。否则会在每时每刻都生成一个新的session id.

session改名示例:

<?php
$previous_name = session_name("WebsiteID");
echo "新的session名为: $previous_name<br />";
?>

● 如何删除session?

1、unset ($_SESSION['xxx']) 删除单个session,unset($_SESSION['xxx']) 用来unregister一个已注册的session变量。其作用和session_unregister()相同。 session_unregister()在PHP5中不再使用,可将之打入冷宫。

unset($_SESSION) 此函数千万不可使用,它会将全局变量$_SESSION销毁,而且还没有可行的办法将其恢复。用户也不再可以注册$_SESSION变量。

2、$_SESSION=array() 删除多个session

3、session_destroy()

注: この関数にはパラメータがなく、戻り値は true です。 Cookie ベースの session(cookie-based session) を使用する場合、ブラウザは Session_start() を使用する前に出力を生成してはなりません。そうしないと、次のエラーが発生します:

<?php // 初始化session. session_start();
/*** 删除所有的session变量..也可用unset($_SESSION[xxx])逐个删除。****/
$_SESSION = array();
/***删除sessin id.由于session默认是基于cookie的,所以使用setcookie删除包含session id的cookie.***/
if (isset($_COOKIE[session_name()])) { setcookie(session_name(), '', time()-42000, '/'); }
// 最后彻底销毁session. session_destroy();
?>

で設定できます。 php.ini で session.auto_start=1 を開始するため、セッションを使用する前に毎回 session_start() を呼び出す必要はありません。ただし、このオプションの有効化にはいくつかの制限があります。session.auto_start が実際に有効化されている場合、セッション内でオブジェクトを再作成するには、セッションを開始する前にクラス定義をロードする必要があるため、オブジェクトをセッションに配置することはできません。

登録されたすべての変数は、リクエストの完了後にシリアル化されます。登録されているが定義されていない変数は、未定義としてマークされます。これらの変数は、ユーザーが後で定義しない限り、その後のアクセスでもセッション モジュールによって定義されません。 🎜🎜警告: 一部のタイプのデータはシリアル化できないため、セッションに保存できません。循環参照を持つリソース変数またはオブジェクトを含めます (つまり、あるオブジェクトがそれ自体への参照を別のオブジェクトに渡します)。 🎜🎜🎜SESSION 変数の登録: 🎜🎜🎜PHP5 は $_SESSION[‘xxx’]=xxx を使用して SESSION グローバル変数を登録します。これは GET、POST、COOKIE の使用法と似ています。 🎜🎜注: session_register()session_unregistersession_is_registered は、php.ini で register_globle が変更されない限り、php5 では使用されなくなりました。 /code>on に設定しますが、セキュリティ上の理由から、<code>register_globle をオフにすることを強くお勧めします。 HTTP_SESSION_VARS の使用は推奨されなくなり、代わりに $_SESSION を使用することが公式に推奨されています。 🎜🎜例: 🎜🎜Page1.php 🎜
session_start()
🎜 セッション ID を渡すには 2 つの方法があります: Cookie URL パラメーター 🎜🎜 セッション モジュールは両方の方法をサポートします。 Cookie はより最適化されていますが、常に利用できるわけではないため、代替手段も提供されています。 2 番目の方法では、セッション ID を URL の途中に直接埋め込みます。 PHP は接続を透過的に変換できます。 PHP 4.2 以降を使用している場合を除き、PHP をコンパイルするときに手動でアクティブ化する必要があります。 Unix では、--enable-trans-sid 構成オプションを使用します。この構成オプションと実行時オプション session.use_trans_sid が両方ともアクティブ化されている (php.ini が変更されている) 場合、相対 URI はセッション ID を含むように自動的に変更されます。 🎜🎜● session_id session_id() は、現在の session_id を設定または取得するために使用されます。 🎜🎜php5 では、session_id() を使用するか、URL に添付された SID を通じて現在のセッションの session_id と session_name を取得できます。 🎜🎜 session_id() に特定の値がある場合、現在の session_id 値が置き換えられます。この関数を使用する前にセッションを開始する必要があります: session_start(); セッション Cookie を使用する場合、session_id() 値が指定されている場合、session_start() が開始されるたびに Cookie 値がクライアントに送信されます。現在の session_id が指定された値と等しいかどうかは関係ありません。 🎜🎜session_id()値が指定されていない場合は、現在の session_id() が返され、現在のセッションが開始されていない場合は、空の文字列が返されます。 🎜🎜● セッションが存在するかどうかを確認しますか? 🎜🎜以前の PHP バージョンでは、通常、セッションが存在するかどうかを確認するために session_is_register() が使用されていました。 $_SESSION['XXX']=XXX を使用してセッション変数を登録する場合、session_is_register() 関数は必要ありません。より長い作品。代わりに isset($_SESSION[‘xxx’]) を使用できます。 🎜🎜● session_id session_regenerate_id() を変更します。変更が成功した場合は true、失敗した場合は false を返します。 🎜🎜この関数を使用すると、現在のセッションの session_id を変更できますが、現在のセッションの他の情報は変更されません。 🎜🎜例: 🎜
$_SESSION=array()/unset($_SESSION[&#39;xxx&#39;])
🎜🎜● session_name() 🎜🎜🎜現在のセッションの名前を返すか、現在のセッションの名前を変更します。 🎜🎜現在のセッションの名前を変更したい場合は、session_start() の前にこの関数を呼び出す必要があります。 🎜🎜注: session_name は数字だけで構成することはできません。少なくとも 1 つの文字を含める必要があります。それ以外の場合は、新しいセッション ID が毎回生成されます。 🎜🎜セッション名の変更例: 🎜
session_destroy()
🎜🎜● セッションを削除するには? 🎜🎜🎜1. unset ($_SESSION['xxx']) 単一セッションを削除します。unset($_SESSION['xxx']) は、登録されたセッション変数の登録を解除するために使用されます。その機能は session_unregister() と同じです。 session_unregister() は PHP5 では使用されなくなったため、廃止される可能性があります。 🎜🎜unset($_SESSION) この関数は使用してはなりません。グローバル変数 $_SESSION が破壊され、それを復元する適切な方法はありません。ユーザーは $_SESSION 変数も登録できなくなります。 🎜🎜2. $_SESSION=array() 複数のセッションを削除します🎜🎜3. session_destroy() 現在のセッションを終了し、セッション内のすべてのリソースをクリアします。 。この関数は、現在のセッションに関連するグローバル変数の設定を解除 (解放) しません。また、PHP のデフォルトのセッションは Cookie に基づいています。Cookie を削除したい場合は、setcookie() 関数を使用する必要があります。 🎜🎜戻り値: ブール値。 🎜🎜関数の説明: この関数は現在のセッションを終了します。この関数にはパラメーターがなく、戻り値は true です🎜。

session_unset() 如果使用了$_SESSION,则该函数不再起作用。由于PHP5必定要使用$_SESSION,所以此函数可以打入冷宫了。

下面是PHP官方关于删除session的案例:

<?php // 初始化session. session_start();
/*** 删除所有的session变量..也可用unset($_SESSION[xxx])逐个删除。****/
$_SESSION = array();
/***删除sessin id.由于session默认是基于cookie的,所以使用setcookie删除包含session id的cookie.***/
if (isset($_COOKIE[session_name()])) { setcookie(session_name(), &#39;&#39;, time()-42000, &#39;/&#39;); }
// 最后彻底销毁session. session_destroy();
?>

由此我们可以得出删除Session的步骤:

session_start()

$_SESSION=array()/unset($_SESSION[&#39;xxx&#39;])

session_destroy()

● SESSION安全:

会话模块不能保证存放在会话中的信息只能被创建该会话的用户看到。根据其存放的数据,还需要采取更多措施来主动保护会话的完整性。

评估会话中携带的数据并实施附加保护措施通常要付出代价,降低用户的方便程度。例如,如果要保护用户免于受简单的社交策略侵害(注:指在 URL 中显示的会话 ID 会被别人在电脑屏幕上看到,或被别的网站通过 HTTP Referer 得到等),则应该启用 session.use_only_cookies。此情形下,客户端必须无条件启用 cookie,否则会话就不工作。

有几种途径会将现有的会话 ID 泄露给第三方。泄露出的会话 ID 使第三方能够访问所有与指定 ID 相关联的资源。

第一,URL 携带会话 ID。如果连接到外部站点,包含有会话 ID 的 URL 可能会被存在外部站点的 Referer 日志中。

第二,较主动的攻击者可能会侦听网段的数据包。如果未加密,会话 ID 会以明文方式在网络中流过。对此的解决方式是在服务器上实施 SSL 并强制用户使用。

默认情况下,所有与特定会话相关的数据都被存储在由 INI 选项 session.save_path 指定的目录下的一个文件中。对每个会话会建立一个文件(不论是否有数据与该会话相关)。这是由于每打开一个会话即建立一个文件,不论是否有数据写入到该文件中。注意由于和文件系统协同工作的限制,此行为有个副作用,有可能造成用户定制的会话处理器(例如用数据库)丢失了未存储数据的会话。上面介绍函数下文将会用到,但还有一些有关session的函数也介绍一下:

session_encode

  • 函数功能:sesssion信息编码

  • 函数原型:string session_encode(void);

  • 返回值:字符串

功能说明:返回的字符串中包含全局变量中各变量的名称与值,形式如:a|s:12:"it is a test\";c|s:4:"lala"; a是变量名 s:12代表变量a的值"it is a test的长度是12 变量间用分号”;”分隔。

session_decode

  • 函数功能:sesssion信息解码

  • 函数原型:boolean session_decode (string data)

  • 返回值:布尔值

功能说明:这个函数可将session信息解码,成功则返回逻辑值true

Php5 不再使用session_id,而是把它变成一个常量SID,并保存在cookie中。如果客户端禁用了cookie,php会自动通过url自动传动传递SID,其条件是设置php.ini中的session.use_trans_sid = 1。此时即使客户端即使禁用了cookie也没关系了。

strip_tags() 来输出 SID 以避免 XSS 相关的攻击。

Session跨页传递问题:

session跨页传递需要考虑三种情况:

  • 客户端禁用了cookie。

  • 浏览器出现问题,暂时无法存取cookie

  • php.ini中的session.use_trans_sid = 0或者编译时没有打开--enable-trans-sid选项 为什么会这样呢?

下面解释一下原因:

Session文件分为两部分:session变量保存在服务器端(默认以文件方式存储session);而session id则以cookie形式保存在客户端。(注意:session默认是基于cookie的)。

当用户的浏览器向服务器提出请求时,同时发送包含session id的cookie(默认情况下)。服务器根据客户端提供的session id来得到用户的文件,即保存在服务器端的session变量值。事实上,session id可以使用客户端的Cookie或者Http1.1协议的Query_String(就是访问的URL的“?”后面的部分)来传送给服务器,然后服务器读取Session的目录……。

也就是说,session id是取得存储在服务上的session变量的身份证。当代码session_start();运行的时候,就在服务器上产生了一个session文件,随之也产生了与之唯一对应的一个session id,定义session变量以一定形式存储在刚才产生的session文件中。通过session id,可以取出定义的变量。跨页后,为了使用session,你必须又执行session_start();将又会产生一个session文件,与之对应产生相应的session id,用这个session id是取不出前面提到的第一个session文件中的变量的,因为这个session id不是打开它的“钥匙”。如果在session_start();之前加代码session_id($session id);将不产生新的session文件,直接读取与这个id对应的session文件。

PHP中的session在默认情况下是使用客户端的Cookie来保存session id的,所以当客户端的cookie出现问题的时候就会影响session了。

必须注意的是:session不一定必须依赖cookie,这也是session相比cookie的高明之处。当客户端的Cookie被禁用或出现问题时,PHP会自动把session id附着在URL中,这样再通过session id就能跨页使用session变量了。但这种附着也是有一定条件的,

其一:“php.ini中的 session.use_trans_sid = 1或者编译时打开打开了--enable-trans-sid选项”;

其二:运行PHP的服务器必须是unix/linux系统,windows不具备此项功能。 明白了以上的道理,我们就可以得出解决session跨页传递问题的三条途径:

1、设置php.ini中的session.use_trans_sid = 1或者编译时打开打开了--enable-trans-sid选项,让PHP自动跨页传递session id。

2、手动通过URL传值、隐藏表单传递session id。

3、用文件、数据库等形式保存session_id,在跨页过程中手动调用。

下面举例说明:

第一种途径:

page1.php

<?php
session_start();
$_SESSION[&#39;var1&#39;]="中华人民共和国";
$url="<a href="."\"s2.php\">下一页</a>"; echo $url;
?>
page2.php
<?php
session_start();
echo "传递的session变量var1的值为:".$_SESSION[&#39;var1&#39;];
?>

运行以上代码,在客户端cookie正常的情况下,应该可以在得到结果“中华人民共和国”。

现在你手动关闭客户端的cookie,再运行,可能得不到结果了吧。如果得不到结果,再“设置php.ini中的session.use_trans_sid = 1或者编译时打开打开了--enable-trans-sid选项”,又得到结果“中华人民共和国”

第二种途径:

s1.php

<?php
session_start();
$_SESSION[&#39;var1&#39;]="中华人民共和国";
$sn = session_id();
$url="<a href="."\"s2.php?s=".$sn."\">下一页</a>";
//PHP5定义了一个常量SID来表示session_id(),$url还可以写成$url=&#39;<a href="page2.php?&#39; . SID . &#39;">下一页</a>&#39;; echo $url;
?>
s2.php
<?php
session_id($_GET[&#39;s&#39;]);
session_start();
echo "传递的session变量var1的值为:".$_SESSION[&#39;var1&#39;];
?>

第三种途径:

login.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Login</title>
<meta http-equiv="Content-Type" content="text/html; charset=??????">
</head>
<body> 请登录:
<form name="login" method="post" action="mylogin1.php">
用户名:<input type="text" name="name">
<br>
口 令:
<input type="password" name="pass">
<br>
<input type="submit" value="登录">
</form>
</body>
</html>
mylogin1.php
<?php
$name=$_POST[&#39;name&#39;];
$pass=$_POST[&#39;pass&#39;];
if(!$name || !$pass)
{ echo "用户名或密码为空,请<a href=\"login.html\">重新登录</a>";
die();
}
if(!($name=="laogong" && $pass=="123"))
{ echo "用户名或密码不正确,请<a href=\"login.html\">重新登录</a>"; die(); }
//注册用户
ob_start();
session_start();
$_SESSION[&#39;user&#39;]= $name;
$psid=session_id(); $fp=fopen("e:\\tmp\\phpsid.txt","w+");
fwrite($fp,$psid);
fclose($fp); //身份验证成功,进行相关操作
echo "已登录<br>";
echo "<a href=\"mylogin2.php\">下一页</a>";
?>
mylogin2.php
<?php
$fp=fopen("e:\\tmp\\phpsid.txt","r");
$sid=fread($fp,1024); fclose($fp);
session_id($sid);
session_start();
if(isset($_SESSION[&#39;user&#39;]) && $_SESSION[&#39;user&#39;]="laogong" )
{
echo "已登录!"; } else { //成功登录进行相关操作 echo "未登录,无权访问";
echo "请<a href=\"login.html\">登录</a>后浏览";
die();
}
?>
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。