<?php
/**
* Handles Memcache Sessions
*
* @property Memcache $pool Memcache Object
*/
class MemcacheSessionModule /*implements \SessionHandlerInterface */
{
const UNIX_PREFIX = 'unix://';
const FILE_PREFIX = 'file://';
const TCP_PREFIX = 'tcp://';
const SCHEME_FILE = 'file';
const SCHEME_TCP = 'tcp';
const SCHEME_UNIX = 'unix';
const ZERO_PORT = ':0';
/**
* Our Memcache Pool
* @var Memcache
*/
private $pool;
public function __construct() {
$this->pool = new Memcache;
}
public function close() {
return $this->pool->close();
}
public function destroy($sessionId) {
}
public function gc($maxLifetime) {
}
public function open($savePath, $name) {
$serverList = self::parseSavePath($savePath);
if (!$serverList) {
return false;
}
foreach ($serverList as $serverInfo) {
$this->pool->addserver(
$serverInfo['host'],
$serverInfo['port'],
$serverInfo['persistent'],
$serverInfo['weight'],
$serverInfo['timeout'],
$serverInfo['retry_interval']
);
}
return true;
}
public function read($sessionId) {
}
public function write($sessionId, $data) {
}
private static function parseSavePath($savePath) {
if (empty($savePath)) {
trigger_error(
"Failed to parse session.save_path (empty save_path)",
E_WARNING);
return false;
}
$serverList = explode(',', $savePath);
$return = array();
foreach ($serverList as $url) {
$url = strtolower($url);
// Swap unix:// to file:// for parse_url
if (substr($url, 0, strlen(self::UNIX_PREFIX)) === self::UNIX_PREFIX) {
$url = self::FILE_PREFIX . substr($url, strlen(self::UNIX_PREFIX));
}
$parsedUrlData = parse_url($url);
if (!$parsedUrlData) {
trigger_error("Failed to parse session.save_path (unable to parse " .
"url, url was '" . $url . "')",
E_WARNING);
return false;
}
// Init optional values
$serverInfo = array(
'persistent' => null,
'weight' => null,
'timeout' => null,
'retry_interval' => null
);
switch ($parsedUrlData['scheme']) {
case self::SCHEME_FILE:
if (substr($parsedUrlData['path'], -2) === self::ZERO_PORT) {
$parsedUrlData['path'] = substr($parsedUrlData['path'], 0, -2);
}
$serverInfo['host'] = self::SCHEME_UNIX . $parsedUrlData['path'];
$serverInfo['port'] = 0;
break;
case self::SCHEME_TCP:
$serverInfo['host'] = self::SCHEME_TCP . $parsedUrlData['host'];
if (array_key_exists('port', $parsedUrlData)) {
$serverInfo['port'] = $parsedUrlData['port'];
} else {
$serverInfo['port'] = (int)ini_get('memcache.default_port');
}
break;
default:
trigger_error("Failed to parse session.save_path (unknown protocol," .
" url was '" . $url . "')",
E_WARNING);
return false;
}
if (array_key_exists('query', $parsedUrlData)) {
$optionList = array();
parse_str($parsedUrlData['query'], $optionList);
if (count($optionList) > 0) {
foreach ($optionList as $key => $value) {
switch ($key) {
case 'persistent':
$serverInfo[$key] = (bool)$value;
break;
case 'weight':
case 'timeout':
case 'retry_interval':
$serverInfo[$key] = (int)$value;
break;
}
}
}
}
$return[] = $serverInfo;
}
return $return;
}
}
$session = new MemcacheSessionModule;
$session->open('unix:///var/run/memcache.sock?weight=123,tcp://127.0.0.1:11211?weight=1&persistent=1&timeout=4');
preferences:
33.2 ms | 402 KiB | 5 Q