您可以使用memcached as your session storage handler in PHP。 Memcached 是一个简单的键值存储,可以通过 TCP 访问;有一个memcached module available for Node.js。
PHP 使用会话 ID 作为键将会话存储在 memcached 中。存储在 memcached 中的会话数据(值)是一个序列化的 PHP 对象,略有不同。你可以在the SO question "Parse PHP Session in Javascript" 阅读更多关于这个不寻常的序列化的信息。不过幸运的是,已经有一个 NPM 模块:php-unserialize。
现在是操作方法。
假设
- memcached 可通过 127.0.0.1:11211 访问
- php.ini(或 php.d/memcache.ini)配置为:
session.save_handler='memcached' 和 session.save_path='tcp://127.0.0.1:11211'
- 你已经安装了所需的 NPM 模块(2):
npm install memcached php-unserialize
- CLI 没问题
准备
首先,为了获得一些测试数据,保存以下 php 脚本 (s.php):
<?php
session_start();
$_SESSION['some'] = 'thing';
echo session_id()."\n";
print_r($_SESSION);
用php s.php 执行它,它应该把东西放在标准输出中:
74ibpvem1no6ssros60om3mlo5
Array
(
[some] => thing
)
好的,现在我们知道会话 id (74ibpvem1no6ssros60om3mlo5),并确认会话数据已设置。要确认它在 memcached 中,您可以运行memcached-tool 127.0.0.1:11211 dump,它提供已知键值对的转储,例如我的测试床中有两个:
Dumping memcache contents
Number of buckets: 1
Number of items : 3
Dumping bucket 2 - 3 total items
add 74ibpvem1no6ssros60om3mlo5 0 1403169638 17
some|s:5:"thing";
add 01kims55ut0ukcko87ufh9dpv5 0 1403168854 17
some|s:5:"thing";
到目前为止,我们已经 1) 在 php 中创建了一个会话 id,2) 将来自 php 的会话数据存储在 memcached 中,以及 3) 通过 CLI 确认数据存在。
使用 Node.js 进行检索
这部分其实很简单。 NPM 模块已经完成了大部分繁重的工作。我编写了一个通过 CLI 运行的小 Node.js 脚本,但你明白了:
var Memcached = require('memcached');
var PHPUnserialize = require('php-unserialize');
var mem = new Memcached('127.0.0.1:11211'); // connect to local memcached
var key = process.argv[2]; // get from CLI arg
console.log('fetching data with key:',key);
mem.get(key,function(err,data) { // fetch by key
if ( err ) return console.error(err); // if there was an error
if ( data === false ) return console.error('could not retrieve data'); // data is boolean false when the key does not exist
console.log('raw data:',data); // show raw data
var o = PHPUnserialize.unserializeSession(data); // decode session data
console.log('parsed obj:',o); // show unserialized object
});
假设上面保存为m.js,它可以用node m.js 74ibpvem1no6ssros60om3mlo5运行,它会输出类似:
fetching data with key: 74ibpvem1no6ssros60om3mlo5
raw data: some|s:5:"thing";
parsed obj: { some: 'thing' }
警告/问题
我的一个 PHP 应用程序在会话值中存储了一些二进制数据(即加密),但密钥和正常会话对象保持不变(如上例所示)。在这种情况下,memcached-tool <host:port> dump 将格式错误的序列化会话字符串 打印到标准输出;我认为这可能与标准输出隔离,但我错了。 使用PHPUnserialize.unserializeSession时,解析数据也有问题(以|分隔)。我在网上尝试了其他一些会话反序列化方法,但没有任何成功。我会假设 memcached 在内部维护正确的数据,因为它与本机 PHP 会话保存处理程序一起使用,所以,在撰写本文时,我不太确定它是反序列化方法还是 memcached NPM 模块只是'没有正确检索/解释数据。当坚持使用 ascii 或 utf-8 等非二进制数据时,它应该可以按预期工作。