Home >Backend Development >PHP Tutorial >PHP implements the method of saving session using MySQL, mysqlsession_PHP tutorial
Session is a variable used by the server to save user information in PHP programming and has a very wide range of application value. The example in this article describes how PHP uses MySQL to save sessions. Share it with everyone for your reference. The specific steps are as follows:
The implementation environment of the example in this article is:
PHP 5.4.24
MySQL 5.6.19
OS X 10.9.4/Apache 2.2.26
1. Code part
1.SQL statement:
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;
2.PHP part code:
<?php /* * 连接数据库所需的DNS、用户名、密码等,一般情况不会在代码中进行更改, * 所以使用常量的形式,可以避免在函数中引用而需要global。 */ define('SESSION_DNS', 'mysql:host=localhost;dbname=db;charset=utf8mb4'); define('SESSION_USR', 'usr'); define('SESSION_PWD', 'pwd'); define('SESSION_MAXLIFETIME', get_cfg_var('session.gc_maxlifetime')); //创建PDO连接 //持久化连接可以提供更好的效率 function getConnection() { try { $conn = new PDO(SESSION_DNS, SESSION_USR, SESSION_PWD, array( PDO::ATTR_PERSISTENT => TRUE, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => FALSE )); return $conn; } catch (Exception $ex) { } } //自定义的session的open函数 function sessionMysqlOpen($savePath, $sessionName) { return TRUE; } //自定义的session的close函数 function sessionMysqlClose() { return TRUE; } /* * 由于一般不会把用户提交的数据直接保存到session,所以普通情况不存在注入问题。 * 且处理session数据的SQL语句也不会多次使用。因此预处理功能的效益无法体现。 * 所以,实际工程中可以不必教条的使用预处理功能。 */ /* * sessionMysqlRead()函数中,首先通过SELECT count(*)来判断sessionID是否存在。 * 由于MySQL数据库提供SELECT对PDOStatement::rowCount()的支持, * 因此,实际的工程中可以直接使用rowCount()进行判断。 */ //自定义的session的read函数 //SQL语句中增加了“expire > time()”判断,用以避免读取过期的session。 function sessionMysqlRead($sessionId) { try { $dbh = getConnection(); $time = time(); $sql = 'SELECT count(*) AS `count` FROM session WHERE skey = ? and expire > ?'; $stmt = $dbh->prepare($sql); $stmt->execute(array($sessionId, $time)); $data = $stmt->fetch(PDO::FETCH_ASSOC)['count']; if ($data = 0) { return ''; } $sql = 'SELECT `data` FROM `session` WHERE `skey` = ? and `expire` > ?'; $stmt = $dbh->prepare($sql); $stmt->execute(array($sessionId, $time)); $data = $stmt->fetch(PDO::FETCH_ASSOC)['data']; return $data; } catch (Exception $e) { return ''; } } //自定义的session的write函数 //expire字段存储的数据为当前时间+session生命期,当这个值小于time()时表明session失效。 function sessionMysqlWrite($sessionId, $data) { try { $dbh = getConnection(); $expire = time() + SESSION_MAXLIFETIME; $sql = 'INSERT INTO `session` (`skey`, `data`, `expire`) ' . 'values (?, ?, ?) ' . 'ON DUPLICATE KEY UPDATE data = ?, expire = ?'; $stmt = $dbh->prepare($sql); $stmt->execute(array($sessionId, $data, $expire, $data, $expire)); } catch (Exception $e) { echo $e->getMessage(); } } //自定义的session的destroy函数 function sessionMysqlDestroy($sessionId) { try { $dbh = getConnection(); $sql = 'DELETE FROM `session` where skey = ?'; $stmt = $dbh->prepare($sql); $stmt->execute(array($sessionId)); return TRUE; } catch (Exception $e) { return FALSE; } } //自定义的session的gc函数 function sessionMysqlGc($lifetime) { try { $dbh = getConnection(); $sql = 'DELETE FROM `session` WHERE expire < ?'; $stmt = $dbh->prepare($sql); $stmt->execute(array(time())); $dbh = NULL; return TRUE; } catch (Exception $e) { return FALSE; } } //自定义的session的session id设置函数 /* * 由于在session_start()之前,SID和session_id()均无效, * 故使用$_GET[session_name()]和$_COOKIE[session_name()]进行检测。 * 如果此两者均为空,则表明session尚未建立,需要为新session设置session id。 * 通过MySQL数据库获取uuid作为session id可以更好的避免session id碰撞。 */ function sessionMysqlId() { if (filter_input(INPUT_GET, session_name()) == '' and filter_input(INPUT_COOKIE, session_name()) == '') { try { $dbh = getConnection(); $stmt = $dbh->query('SELECT uuid() AS uuid'); $data = $stmt->fetch(PDO::FETCH_ASSOC)['uuid']; $data = str_replace('-', '', $data); session_id($data); return TRUE; } catch (Exception $ex) { return FALSE; } } } //session启动函数,包括了session_start()及其之前的所有步骤。 function startSession() { session_set_save_handler( 'sessionMysqlOpen', 'sessionMysqlClose', 'sessionMysqlRead', 'sessionMysqlWrite', 'sessionMysqlDestroy', 'sessionMysqlGc'); register_shutdown_function('session_write_close'); sessionMysqlId(); session_start(); }
2. Introduction
1. When using MySQL to save a session, three key data need to be saved: session id, session data, and session lifetime.
2. Considering how the session is used, there is no need to use the InnoDB engine. The MyISAM engine can achieve better performance. If the environment permits, you can try to use the MEMORY engine.
3. If necessary, you can use the utf8 or utf8mb4 character set for the column that saves the session data; it is not necessary for the column that saves the session id. Generally, you can use the ascii character set, which can save storage costs.
4. The column that saves the session life cycle can be designed according to project needs. For example, datetime type, timestamp type, int type. For datetime and int types, the session generation time or expiration time can be saved.
5. If necessary, you can extend the columns of the session table and modify the read and write functions to support (maintain) relevant columns to save information such as user names.
6. In the current version, you only need to register a custom session maintenance function through session_set_save_handler. There is no need to use the session_module_name('user') function before it.
7. When the read function obtains the data and returns it, PHP will automatically deserialize it. In general, please do not change the data.
8. The date parameter passed by PHP to the write function is the session data after serialization. It can be saved directly. In general, please do not change the data.
9. According to the logic of this code, the PHP configuration option's session lifetime setting is no longer valid. This value can be maintained by itself and does not necessarily need to be obtained through get_cfg_var.
10.sessionMysqlId() function is to avoid collisions when there are a large number of users and multiple web servers. Generally, the session id automatically generated by PHP can meet user requirements.
3. Demand
When the number of users is very large and multiple servers are required to provide applications, using MySQL to store sessions has certain advantages over using session files. For example, it has minimal storage overhead, can avoid the complexity caused by file sharing, can better avoid collisions, and has better performance than session file sharing. Generally speaking, when the number of visits increases sharply, if the problems caused by using the database to save sessions increase linearly, then the problems caused by using session files are almost explosive. Well, let’s put it in a more straightforward way: If your application has a small number of users, you can actually just let PHP handle the session by itself. There is no need to consider MySQL.
4. Reference functions and concepts:
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
I hope the examples described in this article will be helpful to everyone in PHP programming.
For this problem, array storage can be used, and finally output into separated strings, which is a multi-string operation.
I can send you a sample code.
PHP saves sessions by default in the form of files. This can only be used on Windows where the file space overhead is very small, but if we use the file system on uinx or liux, The file space overhead of such a file system is very large. However, sessions must be used all the time. A large number of users will create a lot of session files, which will bring performance problems to the entire server. On the other hand, if If the server adopts the cluster method, the consistency of the session cannot be maintained, so we are ready to use the database method to save the session. In this way, no matter how many servers are used at the same time, they only need to save their sessions on one database server. The integrity of the session can be saved. Please continue reading for details on how to implement it.
By default, PHP sessions are saved in the file format. We can see a line like this in the PHP configuration file php.ini, session.save_handler="files", which means using files. To save the session, if we want to use the database to save it, we need to change it to user mode and rename it session.save_handler="use". However, this only means that we do not use files to store sessions. We also need to Select the database and the tables to create the database.
To establish the database and the table structure of the database, we can use any database that PHP can use. Because the combination of PHP and MySQL is the best, I will use MySQL for the example. Of course, you can change the name to another database according to your needs. At the same time, because MySQL does not have transaction functions, it is faster than other databases. However, saving the session does not require transaction processing, so I think it is better here.
Create database, CREATE DATABASE 'session'; Create table structure CREATE TABLE 'session'( id CHAR(30) NOT NULL , 'user 'CHAR(30), data CHAR(3000) ,PARMIRY BY ('id') );
Write php file
$con =mysql_connection("127.0.0.1","user", "pass");
mysql_select_db("session");
function open($save_path, $session_name)
{
return(true);
}
function close()
{
return(true);
}
function read($id)
{
if($result = mysql_query("SELECT * FROM session WHERE id='$id'"))
{
if($row = mysql_felth_row ($result ))
{ return $row["data"]; }
}
else
{
return "";
}
}
function write($id, $sess_data)
{
if($result = mysql_query("UPDATE session SET data='$sess_data...The rest of the text>>