我有一个session_id,我希望在不将其加载到$_SESSION
数组的情况下读取其数据。请记住,我没有将我的问题局限于某个特定的会话处理程序。
[UPDATE]
这是我的情景:
我有两个(或更多)不同的开源项目,我想合并为一个。这些项目使用会话,但它们相互覆盖是可行的(因为它们都在同一主机和同一域中)。为了防止这种情况发生,我为每个设置了不同的session_names,因此他们将拥有自己的会话。但是我需要编写胶水代码,我必须能够访问这两个会话。我可以将一个加载到$_SESSION
但我必须在不加载的情况下阅读其他内容。
[UPDATE]
考虑到目前为止给出的答案,我想更多地澄清一些事情。我寻找的解决方案是在同一个请求中启动两次(或更多次)会话。并且每次使用不同的session_id。这样我就可以复制会话并加载另一个会话。有了这个说,没有必要唯一的解决方案,但它最接近我正在寻找的东西(只是一个提示)。
答案 0 :(得分:5)
我将逐个启动两个会话并将$ _SESSION值存储在本地数组中。
即
// Loading the first session.
session_name('first_session_name');
session_start();
// Now we have first session variables available in $_SESSION
$_FIRST_SESSION = $_SESSION;
// End current session.
session_write_close();
// Just to make sure nothing remains in the session.
unset($_SESSION);
// Now set the second session name.
session_name('second_session_name');
// Check and see if the second session name has a session id.
if (isset($_COOKIE['second_session_name']))
// There's already a session id for this name.
session_id($_COOKIE['second_session_name']);
else
// We need to generate a new session id as this is the first time.
session_id(sha1(mt_rand()));
session_start();
$_SECOND_SESSION = $_SESSION;
答案 1 :(得分:2)
我会隐藏到你使用$_SESSION
的项目。这些项目应该像以前一样使用$_SESSION
,但您可以管理读取的数据。也可以使用你自己的SessionHandler
,这样当一个项目的$_SESSION
被销毁时,另一个项目就不会被破坏。
您应该在开始会话时包含此文件。然后,请勿在任何地方使用session_start()
。
class SessionAccess implements ArrayAccess {
protected $handler;
public $session;
public function __construct (SharedSessionHandler $handler) {
$this->handler = $handler;
$this->session = $_SESSION;
if (!isset($this->session[NULL]))
$this->session[NULL] = [];
}
public function __get ($project) {
return $this->session[$project];
}
public function offsetGet ($id) {
return $this->getKey($id)[$id];
}
public function __set ($project, $val) {
$this->session[$project] = $val;
}
public function offsetSet ($id, $val) {
return $this->getKey($id)[$id] = $val;
}
public function __isset ($project) { // don't think it should be used with empty() ...
return isset($this->session[$project]);
}
public function offsetExists ($id) {
return isset($this->getKey($id)[$id]);
}
public function __unset ($project) {
$this->session[$project] = [];
}
public function offsetUnset ($id) {
unset($this->getKey($id)[$id]);
}
protected function &getKey ($id) {
return isset($this->session[NULL][$id])?$this->session[NULL]:$this->session[$this->handler->projectMapper()];
}
}
class SharedSessionHandler extends SessionHandler { // we want to preserve write/read functions etc., only put a thin layer of abstraction between
protected $projects = [];
private $writing = false;
private $tmpSessionStore;
public function registerProject ($project_name, $base) {
$this->projects[$base] = $project_name;
if (!isset($_SESSION->$project_name))
$_SESSION->$project_name = [];
}
public function projectMapper () {
$bt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3)[2];
foreach ($this->projects as $base => $name) {
if (substr_compare(realpath($base), realpath($bt["file"]), 0, strlen($base)) === 0)
return $name;
}
return NULL;
}
public function write ($session_id, $session_data) {
if (!$this->writing) {
$this->writing = true;
$this->tmpSessionStore = $_SESSION;
$_SESSION = $_SESSION->session;
session_write_close();
} else {
parent::write($session_id, $session_data);
$_SESSION = $this->tmpSessionStore;
$this->writing = false;
}
}
public function close () { // as session_write_close() _will_ trigger this (prevent writing to closed stream)
return true;
}
public function destroy ($session_id) {
$key = $this->projectMapper();
if ($key === null) {
foreach ($this->projects as $project)
unset($_SESSION->$project);
} else {
unset($_SESSION->$key);
}
}
}
session_set_save_handler($sessionHandler = new SharedSessionHandler());
session_start();
$_SESSION = new SessionAccess($sessionHandler);
如果你使用它,你将为你的所有项目都有一个大的会话。您不必更改任何内容(除了删除所有session_start()
)。
我认为你的每个项目都在它自己的路径中,因此,为了区分不同的$_SESSION
,请使用:
$sessionHandler->registerProject("projectName", __DIR__); // __DIR__ or the path to the project
要访问其他会话,请使用$_SESSION->projectName[$variable]
。
任何注册目录中不的所有内容都将使用相同的全局会话存储。如果未在此全局存储中设置任何密钥,它将从您的本地存储中获取密钥 - 或者在通知时失败。
答案 2 :(得分:0)
使用SessionHandler类及其方法read($session_id)
。
在此处查看更多内容:http://www.php.net/manual/en/class.sessionhandler.php
答案 3 :(得分:0)
如果您的项目在一台服务器上运行,您可以找到存储此会话的位置,并尝试手动读取它而不加载PHP实例(php只是一个示例)。例如,所有通过路径定位的php会话都保存在php.ini中的session.save_path变量中。所以你可以读取这个变量(通过一些脚本解析它[bash?])然后将会话读作普通文件。 对于perl,它取决于会话模块将在项目中使用的内容。在任何情况下,最终它将是一些文件夹,其中包含服务器文件系统中的文件。您需要为使用不同语言的所有项目制定自己的解析规则。