ホームページ >バックエンド開発 >PHPチュートリアル >セッションをデータベースに保存し、PHP で使用する方法

セッションをデータベースに保存し、PHP で使用する方法

不言
不言オリジナル
2018-08-07 10:24:125961ブラウズ

セッションをデータベースに保存し、PHP で使用する方法

この記事では、PHP でセッションをデータベースに保存して使用する方法 (コード付き) を紹介します。これには一定の参照値があります。必要な友人が参照できるようにします。あなたを助けます。

例の説明:

SESSION データ変数をサーバー側に保存する方が安全ですが、想像してみてください。 Xiaonei.com のような大規模な Web サイトでは、毎日 1 億回以上のアクセスがあり、数千万人のユーザーがいる場合、すべてのユーザーの SESSION データがサーバーに保存されると、膨大なサーバー リソースが消費されます。したがって、プログラマーが大規模な Web サイトを作成する場合、SESSION をサーバー側に保存するのは安全ですが、最良の選択ではありません。 SESSION データがデータベースに保存されている場合、サーバーへの 負荷が軽減され、データは比較的安全です。

関連トピックの推奨事項

: php セッション (画像、テキスト、ビデオ、ケースを含む)

##設計プロセス

まず、Mysql データベースに SESSION を保存するテーブルを作成します。

table t_session

という名前のテーブル構造は

セッションをデータベースに保存し、PHP で使用する方法

説明:

session_key: はい

  • session_data<span style="color:#3a3737;"></span> セッション ID の保存に使用されます: シリアル化された $_SESSION[ ];

  • session_time<span style="color:#3a3737;"></span>: タイムスタンプを保存するために使用されます。このタイムスタンプは有効期間を指します。現在のセッションが作成されたときの time() セッションの時間。ここでの session_time の型は int であることに注意してください。これは、データベースを操作するときにサイズ比較を実行できるようにするためです。

#それでは、シリアル化とは何でしょうか?

シリアル化 (シリアル化) は、オブジェクトの状態情報を保存または送信できる形式に変換するプロセスです。シリアル化中、オブジェクトは現在の状態を一時ストレージまたは永続ストレージに書き込みます。後で、オブジェクトの状態をストアから読み取るか逆シリアル化することで、オブジェクトを再作成できます。

$_SESSION[“user”]=”张三”
$_SESSION[“pwd”]=”zhangsan”

シーケンスは文字列になります

user|s:6:"张三";pwd|s:8:"zhangsan";

ここで、sは文字列としての型を表し、数値は文字列の長さを表すため、次のように操作できます。この文字列に .

次のステップはテキスト部分です

session.save_handler

に関連付けられたデータを保存および取得するプロセッサの名前を定義します。セッション。デフォルトは #ファイル # です。ファイルに設定した場合(session.save_handler = files)、PHPの組み込み機構が使用されますが、データベースに保存するなど保存方法をカスタマイズしたい場合は、session_set_save_handler()を使用して設定をカスタマイズします ,ここで話しているのは 2 番目のタイプです。 したがって、php.ini ファイルの

session_set_save_handler

の値を user に変更する必要があります。たとえば、写真:###############

bool session_set_save_handler ( callable open 呼び出し可能 $close呼び出し可能 read 呼び出し可能 write呼び出し可能 destroy呼び出し可能 gc [, callable $create_sid [, callable validate_sid [, callable update_timestamp ]]] )

変更しない場合は、セッション中は彼を無視できますが、変更を加えるときは彼と向き合う必要があります。一般的な関数のパラメーターは変数ですが、この関数のパラメーターは 6 つの関数であるため、これは非常に特殊な関数です (最後の 3 つのパラメーターはオプションのパラメーターなので無視できます)。心配しないで、1 つずつ実行してください。

最初のパラメータ: open(save_path,session_name)、ここの 2 つのパラメータは php によって自動的に渡されます。 save_path は session.save_handler = files の場合の session.save_path で、session_name はサーバーがクライアントを識別するために使用するセッション ID です。ただし、ユーザーがカスタマイズした場合、これら 2 つのパラメータは使用されず、データベースに接続するだけです。 open コールバック関数はクラスのコンストラクターに似ており、セッションが開かれるときに呼び出されます。これは、session_start() を呼び出して自動的または手動でセッションを開始した後に呼び出される最初のコールバック関数です。このコールバック関数は、操作が成功した場合は TRUE を返し、それ以外の場合は FALSE を返します。

2 番目のパラメータ: close()、この関数はパラメータを必要とせず、データベースを閉じるために使用されます。 close コールバック関数は、クラスのデストラクターに似ています。書き込みコールバック関数が呼び出された後に呼び出されます。 session_write_close() 関数が呼び出されると、close コールバック関数も呼び出されます。このコールバック関数は、操作が成功した場合は TRUE を返し、それ以外の場合は FALSE を返します。

3 番目のパラメーター: read($key)、ここでのパラメーターはセッション ID であり、PHP によって自動的に渡されます。渡す前提は、セッション ID があることです。そうでない場合、このパラメータは空の文字列を返します。データベースに対応するデータがない場合は、空の文字列を返す必要があることに注意してください。返さない場合は、エラーが報告されます。セッション内にデータがある場合、読み取りコールバック関数はセッション データ (この場合、テーブル t_session から取得した session_data) をエンコード (シリアル化) する文字列を返す必要があります。 session_start() 関数を呼び出して自動的または手動でセッションを開始した後、PHP は内部で読み取りコールバック関数を呼び出してセッション データを取得します。 read を呼び出す前に、PHP は open コールバック関数を呼び出します。読み取りコールバックによって返されるシリアル化された文字列の形式は、書き込みコールバック関数がデータを保存するときの形式とまったく同じである必要があります。 PHP は、返された文字列を自動的に逆シリアル化し、$_SESSION スーパー グローバル変数に値を設定します。

4 番目のパラメーター: write($key,$data)、これら 2 つのパラメーターも PHP によってこの関数に自動的に渡されます。$key はセッション ID に対応し、$data はセッション ID に対応します。現在の (書き込み関数は通常、スクリプトの実行が完了した後に呼び出されるため) シリアル化プロセッサーによってスクリプトによって処理されたセッション変数 ($_SESSION["user"]="Zhang San"$_SESSION["pwd"] など)上記 =”zhangsan”) を実行すると、session.serialize_handler の設定値に従って、PHP によってセッション データのシリアル化処理が完了します。シリアル化されたデータはセッション ID に関連付けられて保存されます。読み取りコールバック関数を呼び出してデータを取得する場合、返されるデータは書き込みコールバック関数に渡されたデータと完全に一致している必要があります。スクリプトの実行が完了するか、session_write_close() 関数が呼び出された後、PHP はこのコールバック関数を呼び出します。このコールバック関数を呼び出した後、PHP は内部で close コールバック関数を呼び出すことに注意してください。

注:PHP は、出力ストリームが書き込まれて閉じられるまで書き込みコールバック関数を呼び出しません。そのため、書き込みコールバック関数内のデバッグ情報はブラウザーに出力されません。書き込みコールバック関数でデバッグ出力を使用する必要がある場合は、デバッグ出力をファイルに書き込むことをお勧めします。

第五个参数:  destroy($key),当调用 session_destroy() 函数, 或者调用 session_regenerate_id() 函数并且设置 destroy 参数为 TRUE 时, 会调用此回调函数。用来注销session对应的SESSION键值,此回调函数操作成功返回 TRUE,反之返回 FALSE。它就是人们常常在点击注销登录的时候用到的函数。后面会有这个小细节。

第六个参数:  gc(expire_time),这个函数的参数在默认机制下就是session.gc_maxlifetime设置的session有效时间。但是,user机制下session的过期时间在就是表里session_time,所以这里不需要传递参数的。为了清理会话中的旧数据,PHP 会不时的调用垃圾收集回调函数。 调用周期由 session.gc_probability 和 session.gc_pisor 参数控制。此回调函数操作成功返回 TRUE,反之返回 FALSE。

至此六个函数已经介绍完了,但是其中有许多需要说明的:

1、在open函数中本来是要传递save__path,目的是用来在这个路径下找到与session_name相对应的文件,然后通过read()函数来读取其中的数据,然后通过反序列化处理器将取到的字符串反序列化,在通过php自动填充各个$_session超全局变量。或者write函数来将序列化的数据存入这个路径下的文件。那么这里面的路径在非默认机制下难道就不需要吗,答案是肯定的*_*。当在非默认机制下,调试输出session_save_path,其结果为空值;而且如果未设置存储的路径,那被填充的$_session变量也只能在当前页面使用,而不能在别的页面使用,可以这样测试:在另一个页面利用session_start()函数打开会话,然后输出session_id和var_dump($_session),得到的是上一次浏览时服务器给客户端的session_id,但是$_session输出的是空数组(当然我这里只是大概的说一下我在验证时的过程)。其实我想说的就是我们在自定义会话存储机制的时候,是不需要自定义路径的,不然为什么还要存入数据库呢?    

那么怎么在其他页面也能读取到$_session[]里面的值呢?

 引入这个函数,即将六个 回调函数和session_set_save_handler放入一个文件里,然后在session_start()前用include()引入!

2、那他们的执行顺序是怎样呢?有点晕吧,来总结一下:首先session_start()函数打开session操作句柄,然后read函数读取数据,当脚本执行结束的时候执行write函数然后是close函数若有session_destroy()则执行完。

3、上面我提到过PHP 会在输出流写入完毕并且关闭之后才调用 write 回调函数,这个可把我玩坏啦,小编在上面可绕了不久呀,不然我也不会在write函数里调试那么久了!不过我也因此了解了register_shutdown_function这个函数,下面附上这个函数的特点吧:register_shutdown_function()是指在执行完所有PHP语句后再调用函数,不要理解成客户端关闭流浏览器页面时调用函数。

可以这样理解调用条件:
1、当页面被用户强制停止时
2、当程序代码运行超时时
3、当PHP代码执行完成时,代码执行存在异常和错误、警告

好了以上该说的都说完了,附上代码吧:

index.php用户登录界面

<?php


include("session_set_save_handler.php");//引入自定义的会话存储机制


if(isset($_GET["login"])){//判断login是否有值,若有值则要进行注销,


session_start();//只要需要 用到$_session变量的地方,就需要开启回调函数open


session_destroy();//这里就是上文提到的 小细节了,当有session_destroy的时候,它是先于read回调函数执行的


}else{


session_start();


if(isset($_SESSION["user"])){//判断此值是否有定义,若有定义则说明 存入的session还未到期,则直接转到主内容


echo "<script>alert(&#39;您不久前刚来过&#39;);window.location.href=&#39;main.php&#39;;</script>";

}

}

?>

<html>

<meta charset="utf-8">

<body>

<form action="index_ok.php" method="post">

账    户:<input type="text" name="user"><br>

密    码:<input type="text" name="pwd">

<input type="submit" name="sub">

</form>

</body>

</html>

index_ok.php表单提交处理文件

<?php


include("session_set_save_handler.php");


session_start();


if($_POST["sub"]){//$_post["sub"]它若有值就是 提交查询


echo $_POST["sub"];


if($_POST["user"]!=""&&$_POST["pwd"]!=""){


$_SESSION["user"]=$_POST["user"];


$_SESSION["pwd"]=$_POST["pwd"];//这里自定义的会话管理机制将会调用回调函数write,将已由序列化处理器处理好的(由$_session[]变量形成)字符串写入数据库


echo "<script>alert(&#39;登录成功!&#39;);window.location.href=&#39;main.php&#39;;</script>";

}

}


?>

main.php主内容页

<?php


include("session_set_save_handler.php");


session_start();


if(isset($_SESSION["user"])){


echo "欢迎".$_SESSION["user"];

echo "<a href=&#39;index.php?login=0&#39;>注销</a>";


}else{


echo "您还没登录,请先登录!";

echo "<a href=&#39;index.php&#39;>登录</a>";

}


?>

session_set_save_handler.php自定义session存储机制函数文件

<?php

//打开会话

function open(){


global $con;//使用全局变量


$con=mysqli_connect("localhost","root","123456","mysql")or die("数据库连接失败!");


mysqli_query($con,"set names utf8");


return(true);


}

//关闭数据库

function close(){


global $con;


mysqli_close($con);


return(true);


}

//读取session_data

function read($key){


global $con;

$time=time();

//不读取已过期的session

$sql="select session_data from t_session where session_key=&#39;$key&#39; and session_time>$time";


$result=mysqli_query($con,$sql)or die("查询失败!");


if (!$result) {//用来检查出现再数据库部分的错误,很有用


printf("Error: %s\n", mysqli_error($con));//%s表示的是字符串,这是c里面的


exit();

}


$row=mysqli_fetch_array($result);//or die()会终止后面的程序!


if($row!=false){


return($row["session_data"]);


}else{


return "";//再次强调如果空值 ,则一定 要返回”“而不是false


}


}

//存储session

function write($key,$data){



global $con;




$over_time=time()+60;//注意time()为时间戳,在mysql中的数据类型不可用用date,datetime,timestamp来存储


$sql="select session_data from t_session where session_key=&#39;$key&#39;";


$re=mysqli_query($con,$sql);


$result=mysqli_fetch_array($re);


//若$result为false,即结果 为空,说明数据库中未存有相应的session_id,那么就插入,如果不为空,那即使还有未过期的session_id,这是应更新


if($result==false){




$sql="insert into t_session(session_key,session_data,session_time ) values(&#39;$key&#39;,&#39;$data&#39;,$over_time)";//字符串的时候要加单引号,数字的时候是不用加的


$result=mysqli_query($con,$sql);


if (!$result) {//用来检查出现再数据库部分的错误,很有用

printf("Error: %s\n", mysqli_error($con));//%s表示的是字符串,这是c里面的

exit();

}




}else{




$sql="update t_session set session_key=&#39;$key&#39;,session_data=&#39;$data&#39;,session_time=$over_time where session_key=&#39;$key&#39;";


$result=mysqli_query($con,$sql);

}




return($result);


}

清楚相应的session数据

function destroy($key){




global $con;


$sql="delete from t_session where session_key=&#39;$key&#39;";


$result=mysqli_query($con,$sql);


return($result);


}


//执行垃圾回收


function overdue($expire_time){//这个参数是自动传进去的,就是session.gc_maxlifetime最大有效时间,例如1440s;


global $con;


$time=time();


$sql="delete from t_session where session_time<$time";


$result=mysqli_query($sql);


return($result);


}


session_set_save_handler(&#39;open&#39;,&#39;close&#39;,&#39;read&#39;,&#39;write&#39;,&#39;destroy&#39;,&#39;overdue&#39;);


?>

相关文章推荐:

php使用PHPMailer如何发送邮件(附代码)

PHP中常用的一些功能总结(归纳)

以上がセッションをデータベースに保存し、PHP で使用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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