Sessionの中国語訳は「セッション」といい、本来の意味は、例えば電話をかける場合、受話器を取るまでの一連のプロセス、始まりと終わりのある一連の動作・メッセージを指します。ダイヤルから電話を切るまでをセッションと呼ぶことができます。現在の社会におけるセッションの理解は非常に混乱しています。「ブラウザ セッション中、...」という言葉が時々見られますが、ここでのセッションはブラウザ ウィンドウが開いてから閉じるまでの期間を指します。 「セッション中のユーザー(クライアント)」という文に言及する場合、ユーザーの一連のアクション(通常は、ログインから商品の購入、チェックアウトまでなど、特定の目的に関連する一連のアクション)を指す場合があります。ただし、このようなオンライン ショッピング プロセスは、単に接続を参照しているだけの場合があります。
ただし、セッションという言葉がネットワーク プロトコルに関連付けられている場合、多くの場合、「接続指向」および/または「状態の維持」という 2 つの意味が含まれます。「接続指向」とは、通信する当事者が通信を確立する前に最初に通信する必要があることを意味します。電話をかけるなどの通信チャネルがあり、相手が電話に出るまで通信を開始できません。 「ステータスの維持」とは、通信相手が一連のメッセージを相互に依存できるように関連付けることができることを意味します。たとえば、ウェイターは、再び来た古い顧客を認識し、その顧客が前回店に 1 ドルを借りていたことを思い出すことができます。 。このカテゴリの例は、「TCP セッション」または「POP3 セッション」です。
この混乱が元に戻せないことを考えると、セッションを定義するための統一基準を持つことは困難です。セッション関連の情報を読むときは、文脈に頼って理解を推測するしかありません。しかし、次のように理解することができます。たとえば、電話をかけるとき、電話をかけた瞬間から電話を切る瞬間まで、電話は接続されたままであるため、この接続状態はセッションと呼ばれます。これは、訪問者と Web サイト全体との間の対話中に常に存在するパブリック変数であり、クライアントが COOKIE をサポートしていない場合、データが正しく安全であることを保証するために、SESSION 変数が使用されます。 Web サイトの訪問者には、一意の識別子、いわゆるセッション ID が割り当てられます。これは、クライアント側の Cookie に保存されるか、URL 経由で渡されます。
SESSION の発明は、HTTP プロトコルの制限を補います。HTTP プロトコルはステートレス プロトコルとみなされ、サーバー側で応答が完了すると、サーバーはブラウザとの接続を失います。これは、HTTP プロトコルの本来の目的と一致しています。クライアントは、サーバーに特定のファイルをダウンロードするよう要求するだけで済みます。クライアントとサーバーは、それぞれのリクエストの過去の動作を記録する必要はありません。顧客と自動販売機、または通常の(非会員制)ハイパーマーケット。
そのため、ユーザーがこのIDとしてWebサーバーに再度リクエストを行う際の確認のために、ユーザーの関連情報がSESSION(Cookieは別の解決策)を通じて記録されます。セッションの発明により、ユーザーは複数のページを切り替えるときに自分の情報を保存できるようになります。ウェブサイトのプログラマーなら誰しも経験があると思いますが、各ページの変数は次のページでは使用できません(フォームやURLも実装できますが、非常に不十分な方法です)。一方、SESSIONに登録された変数はグローバルとして使用できます。変数。
それでは、SESSION の用途は何でしょうか?オンラインで買い物をするとき、誰もがショッピング カートを使用したことがあります。いつでも選択した商品をショッピング カートに追加し、最後にレジに行って会計を行うことができます。プロセス全体を通じて、ショッピング カートは選択した商品を一時的に保存する役割を果たします。これは、ユーザーの ID 認証やプログラムのステータスを追跡するために使用されます。記録、ページ間のパラメータの受け渡しなど。
COOKIE テクノロジーは 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(): セッションを開始するか、既存のセッションを返します。
注: この関数にはパラメータがなく、戻り値は true です。 Cookie ベースのセッションを使用する場合、ブラウザーは Session_start() を使用する前に出力を生成してはなりません。そうしないと、次のエラーが発生します:
リーリーphp.ini で session.auto_start=1 を有効にできるため、セッションを使用する前に毎回 session_start() を呼び出す必要はありません。ただし、このオプションの有効化にはいくつかの制限があります。session.auto_start が実際に有効になっている場合、セッション内でオブジェクトを再作成するには、セッションを開始する前にクラス定義をロードする必要があるため、オブジェクトをセッションに配置することはできません。
登録されたすべての変数は、リクエストの完了後にシリアル化されます。登録されているが定義されていない変数は、未定義としてマークされます。これらの変数は、ユーザーが後で定義しない限り、その後のアクセスでもセッション モジュールによって定義されません。
警告: 一部の種類のデータはシリアル化できないため、セッションに保存できません。循環参照を持つリソース変数またはオブジェクトを含めます (つまり、あるオブジェクトがそれ自体への参照を別のオブジェクトに渡します)。
SESSION変数を登録します:
PHP5 は $_SESSION[‘xxx’]=xxx を使用して SESSION グローバル変数を登録します。 GET、POST、COOKIEの使用方法は同様です。
注: session_register()、session_unregister、session_is_registered は、php.ini で register_globle が on に設定されていない限り、php5 では使用されなくなりました。ただし、セキュリティ上の理由から、 register_globle をオフにすることを強くお勧めします。 HTTP_SESSION_VARS の使用は推奨されなくなり、代わりに $_SESSION を使用することが公式に推奨されています。例:
ページ1.php
リーリーPage2.php
リーリー1 つは Cookie で、もう 1 つは 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 を設定または取得するために使用されます。 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_regenerate_id() は、変更が成功した場合は true を返し、失敗した場合は false を返します。 この関数を使用すると、現在のセッションの session_id を変更できますが、現在のセッションの他の情報は変更されません。例:
リーリー現在のセッションの名前を返すか、現在のセッションの名前を変更します。現在のセッションの名前を変更する場合は、session_start() の前にこの関数を呼び出す必要があります。注: session_name は数字だけで構成することはできません。少なくとも 1 つの文字を含める必要があります。それ以外の場合は、毎回新しいセッション ID が生成されます。セッション名の変更の例:
リーリーunset ($_SESSION['xxx']) は単一のセッションを削除します。unset($_SESSION['xxx']) は登録されたセッション変数の登録を解除するために使用されます。その機能は session_unregister() と同じです。 session_unregister() は PHP5 では使用されなくなったため、廃止される可能性があります。 unset($_SESSION) この関数は使用してはなりません。グローバル変数 $_SESSION が破壊され、それを復元する適切な方法はありません。ユーザーは $_SESSION 変数を登録できなくなります。
$_SESSION=array() 複数のセッションを削除します
session_destroy() 現在のセッションを終了し、セッション内のすべてのリソースをクリアします。この関数は、現在のセッションに関連するグローバル変数の設定を解除 (解放) しませんし、クライアントのセッション Cookie を削除しません。 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(), '', time()-42000, '/'); } // 最后彻底销毁session. 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 文件分为两部分: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跨页传递问题的三条途径:
下面举例说明:
第一种情况:
page1.php
<?php session_start(); $_SESSION['var1']="中华人民共和国"; $url="<a href="."\"s2.php\">下一页</a>"; echo $url; ?>
page2.php
<?php session_start(); echo "传递的session变量var1的值为:".$_SESSION['var1']; ?>
运行以上代码,在客户端cookie正常的情况下,应该可以在得到结果“中华人民共和国”。
现在你手动关闭客户端的cookie,再运行,可能得不到结果了吧。如果得不到结果,再“设置php.ini中的session.use_trans_sid = 1或者编译时打开打开了--enable-trans-sid选项”,又得到结果“中华人民共和国”。
第二种途径:
s1.php
<?php session_start(); $_SESSION['var1']="中华人民共和国"; $sn = session_id(); //PHP5定义了一个常量SID来表示session_id(),$url还可以写成$url='<a href="page2.php?' . SID . '">下一页</a>'; $url="<a href="."\"s2.php?s=".$sn."\">下一页</a>"; echo $url; ?>
s2.php
<?php session_id($_GET['s']); session_start(); echo "传递的session变量var1的值为:".$_SESSION['var1']; ?>
第三种途径:
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['name']; $pass=$_POST['pass']; 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['user']= $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['user']) && $_SESSION['user']="laogong" ) { echo "已登录!"; } else { //成功登录进行相关操作 echo "未登录,无权访问"; echo "请<a href=\"login.html\">登录</a>后浏览"; die(); } ?>