PHPはMySQLでセッションを保存
25214 ワード
実装環境:
一、コード
二、紹介 MySQLを使用してセッションを保存するには、セッションid、セッションデータ、セッションライフ期間の3つの重要なデータを保存する必要があります. セッションの使い方を考えると、InnoDBエンジンを使う必要はなく、MyISAMエンジンはより良い性能を得ることができます.環境が許可されている場合は、MEMORYエンジンを使用してみてください. sessionデータの列を保存し、必要に応じてutf 8またはutf 8 mb 4文字セットを使用することができます.セッションidのカラムを保存する必要はありません.一般的にascii文字セットを使えばいいので、ストレージコストを節約できます. sessionライフサイクルの列を保存し、工事の必要に応じて設計することができます.例えばdatetimeタイプ、timestampタイプ、intタイプです.datetime、intタイプの場合、セッション生成時間または有効期限を保存できます. ユーザ名などの情報を保存するために、セッションテーブルのカラムを拡張し、読み取り、書き込み関数を変更して、関連するカラムをサポート(メンテナンス)する必要がある場合. 現在のバージョンはセッションを通過する限りset_save_handlerはカスタムセッションメンテナンス関数を登録すればいいので、その前にsession_を使用する必要はありません.module_name('user')関数. read関数がデータを取得して返されると、PHPは自動的に逆シーケンス化されます.一般的にはデータは変更しないでください. PHPがwrite関数に渡すdateパラメータはシーケンス化されたセッションデータであり、そのまま保存すればよいので、一般的にはデータを変更しないでください. このセグメントコードの論理に従って、PHP構成オプションはセッションのライフサイクルの設定についてもう有効ではありません.この値は自分で維持することができます.get_を通過する必要はありません.cfg_var取得. sessionMysqlId()関数は,大ユーザ量,複数のWebサーバの場合の衝突を回避するためであり,一般的にPHPが自動的に生成するsession idはユーザの要求を満たすことができる. がなくなった 三、需要
ユーザー数が非常に多く、複数のサーバでアプリケーションを提供する必要がある場合、MySQLストレージセッションを使用することは、セッションファイルを使用することに対して一定の優位性を有します.たとえば、ファイル共有による複雑さを回避したり、セッション・ファイル共有よりもパフォーマンスが向上したりするなど、ストレージ・オーバーヘッドを最小限に抑えることができます.全体的に、アクセスが急増している場合、データベースを使用してセッションを保存する問題が線形に増加している場合、セッションファイルを使用する問題はほとんど爆発的です.では、もっと率直な言い方に変えましょう.もしあなたのアプリケーションのユーザー量が少ないなら、PHPに自分でsessionを処理させておけばいいです.MySQLを考える必要はありません.
四、参考
PHP 5.4.24
MySQL 5.6.19
OS X 10.9.4/Apache 2.2.26
一、コード
CREATE TABLE `session` (
`skey` char(32) CHARACTER SET ascii NOT NULL,
`data` text COLLATE utf8mb4_bin,
`expire` int(11) NOT NULL,
PRIMARY KEY (`skey`),
KEY `index_session_expire` (`expire`) USING BTREE
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
1 <?php
2 /*
3 * DNS、 、 , ,
4 * , global。
5 */
6 define('SESSION_DNS', 'mysql:host=localhost;dbname=db;charset=utf8mb4');
7 define('SESSION_USR', 'usr');
8 define('SESSION_PWD', 'pwd');
9 define('SESSION_MAXLIFETIME', get_cfg_var('session.gc_maxlifetime'));
10
11 // PDO
12 //
13 function getConnection() {
14 try {
15 $conn = new PDO(SESSION_DNS, SESSION_USR, SESSION_PWD, array(
16 PDO::ATTR_PERSISTENT => TRUE,
17 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
18 PDO::ATTR_EMULATE_PREPARES => FALSE
19 ));
20 return $conn;
21 } catch (Exception $ex) {
22
23 }
24 }
25
26 // session open
27 function sessionMysqlOpen($savePath, $sessionName) {
28 return TRUE;
29 }
30
31 // session close
32 function sessionMysqlClose() {
33 return TRUE;
34 }
35 /*
36 * session, 。
37 * session SQL 。 。
38 * , 。
39 */
40 /*
41 * sessionMysqlRead() , SELECT count(*) sessionID 。
42 * MySQL SELECT PDOStatement::rowCount() ,
43 * , rowCount() 。
44 */
45 // session read
46 //SQL “expire > time()” , session。
47 function sessionMysqlRead($sessionId) {
48 try {
49 $dbh = getConnection();
50 $time = time();
51
52 $sql = 'SELECT count(*) AS `count` FROM session '
53 . 'WHERE skey = ? and expire > ?';
54 $stmt = $dbh->prepare($sql);
55 $stmt->execute(array($sessionId, $time));
56 $data = $stmt->fetch(PDO::FETCH_ASSOC);
57 if ($data['count'] = 0) {
58 return '';
59 }
60
61 $sql = 'SELECT `data` FROM `session` '
62 . 'WHERE `skey` = ? and `expire` > ?';
63 $stmt = $dbh->prepare($sql);
64 $stmt->execute(array($sessionId, $time));
65 $data = $stmt->fetch(PDO::FETCH_ASSOC);
66 return $data['data'];
67 } catch (Exception $e) {
68 return '';
69 }
70 }
71
72 // session write
73 //expire +session , time() session 。
74 function sessionMysqlWrite($sessionId, $data) {
75 try {
76 $dbh = getConnection();
77 $expire = time() + SESSION_MAXLIFETIME;
78
79 $sql = 'INSERT INTO `session` (`skey`, `data`, `expire`) '
80 . 'values (?, ?, ?) '
81 . 'ON DUPLICATE KEY UPDATE data = ?, expire = ?';
82 $stmt = $dbh->prepare($sql);
83 $stmt->execute(array($sessionId, $data, $expire, $data, $expire));
84 } catch (Exception $e) {
85 echo $e->getMessage();
86 }
87 }
88
89 // session destroy
90 function sessionMysqlDestroy($sessionId) {
91 try {
92 $dbh = getConnection();
93
94 $sql = 'DELETE FROM `session` where skey = ?';
95 $stmt = $dbh->prepare($sql);
96 $stmt->execute(array($sessionId));
97 return TRUE;
98 } catch (Exception $e) {
99 return FALSE;
100 }
101 }
102
103 // session gc
104 function sessionMysqlGc($lifetime) {
105 try {
106 $dbh = getConnection();
107
108 $sql = 'DELETE FROM `session` WHERE expire < ?';
109 $stmt = $dbh->prepare($sql);
110 $stmt->execute(array(time()));
111 $dbh = NULL;
112 return TRUE;
113 } catch (Exception $e) {
114 return FALSE;
115 }
116 }
117
118 // session session id
119 /*
120 * session_start() ,SID session_id() ,
121 * $_GET[session_name()] $_COOKIE[session_name()] 。
122 * , session , session session id。
123 * MySQL uuid session id session id 。
124 */
125 function sessionMysqlId() {
126 if (filter_input(INPUT_GET, session_name()) == '' and
127 filter_input(INPUT_COOKIE, session_name()) == '') {
128 try {
129 $dbh = getConnection();
130 $stmt = $dbh->query('SELECT uuid() AS uuid');
131 $data = $stmt->fetch(PDO::FETCH_ASSOC);
132 $data = str_replace('-', '', $data['uuid']);
133 session_id($data);
134 return TRUE;
135 } catch (Exception $ex) {
136 return FALSE;
137 }
138
139 }
140 }
141
142 //session , session_start() 。
143 function startSession() {
144 session_set_save_handler(
145 'sessionMysqlOpen',
146 'sessionMysqlClose',
147 'sessionMysqlRead',
148 'sessionMysqlWrite',
149 'sessionMysqlDestroy',
150 'sessionMysqlGc');
151 register_shutdown_function('session_write_close');
152 sessionMysqlId();
153 session_start();
154 }
二、紹介
ユーザー数が非常に多く、複数のサーバでアプリケーションを提供する必要がある場合、MySQLストレージセッションを使用することは、セッションファイルを使用することに対して一定の優位性を有します.たとえば、ファイル共有による複雑さを回避したり、セッション・ファイル共有よりもパフォーマンスが向上したりするなど、ストレージ・オーバーヘッドを最小限に抑えることができます.全体的に、アクセスが急増している場合、データベースを使用してセッションを保存する問題が線形に増加している場合、セッションファイルを使用する問題はほとんど爆発的です.では、もっと率直な言い方に変えましょう.もしあなたのアプリケーションのユーザー量が少ないなら、PHPに自分でsessionを処理させておけばいいです.MySQLを考える必要はありません.
四、参考
1 http://cn2.php.net/manual/zh/function.session-set-save-handler.php
2 http://cn2.php.net/manual/zh/session.idpassing.php
3 http://cn2.php.net/manual/zh/pdo.connections.php
4 http://cn2.php.net/manual/zh/pdo.prepared-statements.php
5 http://dev.mysql.com/doc/refman/5.1/zh/sql-syntax.html#insert