使用 PDO 方式将 Session 保存到 MySQL 数据中

类:

<?php

/* 使用数据库保存session */

class DBHandler implements SessionHandlerInterface {

	protected $dbh;
	
	public function open($save_path, $name) {
		try {
			$this->connect($save_path, $name);
			return true;
		} catch(PDOException $e) {
			echo $e->getMessage();
			return false;
		}
	}

	public function close() {
		return true;
	}

	public function destroy($session_id) {
		$sth = $this->dbh->prepare("DELETE FROM sessions WHERE session_id = ?");
		$sth->execute(array($session_id));
		return true;
	}

	public function gc($maxlifetime) {
		$sth = $this->dbh->prepare("DELETE FROM sessions WHERE last_update < ?");
		$sth->execute(array(time() - $maxlifetime));
		return true;
	}

	public function read($session_id) {
		$sth = $this->dbh->prepare("SELECT session_data FROM sessions WHERE session_id = ?");
		$sth->execute(array($session_id));
		$row = $sth->fetch(PDO::FETCH_NUM);
		if(count($row) == 0) {
			return '';
		} else {
			return $row[0];
		}
	}

	public function write($session_id, $session_data) {
		date_default_timezone_set('PRC');
		$now = time();
		$sth = $this->dbh->prepare("UPDATE sessions SET session_data = ?,
			last_update = ? WHERE session_id = ?");
		$sth->execute(array($session_data, $now, $session_id));
		if($sth->rowCount() == 0) {
			$sth2 = $this->dbh->prepare("INSERT INTO sessions (session_id, session_data, last_update) VALUES (?,?,?)");
			$sth2->execute(array($session_id, $session_data, $now));
		}
	}

	public function createTable($save_path, $name, $connect = true) {
		if($connect) {
			$this->connect($save_path, $name);
		}
		$sql =<<<_SQL_
CREATE TABLE sessions (
	session_id VARCHAR(64) NOT NULL,
	session_data MEDIUMTEXT NOT NULL,
	last_update INT NOT NULL,
	PRIMARY KEY (session_id)
)
_SQL_;
	$this->dbh->exec($sql);
	}

	public function connect($save_path) {
		$parts = parse_url($save_path);
		parse_str($parts['query'], $query);

		//$dsn格式:mysql:host=localhost;dbname=test
		$dsn = $parts['scheme'].":host=".$parts['host'].";dbname=".$query['dbname'];
		$user = $query['user'];
		$password = $query['password'];

		$this->dbh = new PDO($dsn, $user, $password);
		$this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

		try {
			$this->dbh->query('SELECT 1 FROM sessions LIMIT 1');
		} catch(Exception $e) {
			$this->createTable($save_path, NULL, false);
		}
	}
}

  

使用:

<?php

include './db.php';

ini_set('session.save_path', "mysql://localhost?user=root&password=&dbname=test");
ini_set('session.gc_maxlifetime', 5);
ini_set('session.gc_divisor', 2);
session_set_save_handler(new DBHandler);

session_start();

if(! isset($_SESSION['visits'])) {
	$_SESSION['visits'] = 0;
}

$_SESSION['visits']++;
echo '你是第 '.$_SESSION['visits'].' 次访问';

 

参考:

<PHP Cookbook>3'rd 

原文地址:https://www.cnblogs.com/dee0912/p/5399812.html