我可以使用php Sessions在多个客户端之间共享Session变量吗?

时间:2013-03-31 08:07:14

标签: php session-variables

我想知道的是,如果我可以为多个客户端共享一个Session变量。 就像他们可以使用完全相同的Object。下面的例子将说明我想做什么。

客户端1:

start_session();
include('somelcass.php');
//some code...
$someobj = new someclass();
$_SESSION['myobject'] = serialize($someobj);
$id = sha1("somephrase");
set_session_var_for_other_users_by_id('myobject', $id);

客户端2:

start_session();
include('somelcass.php');
$id = sha1("somephrase");
get_sessionvars_from_other_users($id);
$someobj = unserialize($_SESSION['myobject']);
//now use someobj from class someclass

我的另外一个问题是: 您是否建议使用某些会话扩展,例如:sessionPsql

4 个答案:

答案 0 :(得分:4)

首先回答你的上一个问题:

您链接的Session PgSQLDocs PostgreSQL会话保存处理程序。您可以配置使用会话保存处理程序而不是默认会话保存处理程序。默认session save handler in PHP是将会话存储到磁盘( files )。如果您使用PostgreSQL的保存处理程序,则会将其保存到PostgreSQL数据库中( pgsql )。

如果要允许从多个Web服务器(扩展应用程序)访问会话存储,或者在您的情况下(可能)允许访问具有SQL查询的所有会话,则在数据库中保存会话是有意义的,尽管通常a tailored session save handler是为此定义的(可以基于PgSQL会话保存处理函数)。

回答你的第一个问题:

是的,只要您有对相关对象的引用并且您知道如何访问它,就可以这样做。这可以通过手动访问会话存储或通过自己共享会话以及切换会话来访问其他会话数据来完成。这取决于您的需求,在您的情况下,可能更容易访问由ID存储的序列化数据在一些与会话无关的额外表中。如果您不再需要数据,您应该考虑如何处理数据,例如一段时间不活动后将其移除。最后,您正在以可行的方式编写自己的会话实现。版本4之前的PHP没有开箱即用的会话支持,现在它的会话支持非常轻量级,所以如果你需要做更多特定的事情,你通常会自己编写。

因此,多个客户端可以使用相同的会话(共享会话),这实际上也是一种攻击webapps(session hijackingAttack)的方法,但只要“劫持”是在应用程序数据流中,我没有看到任何技术上的错误。在PHP中,这意味着您需要关闭当前会话,打开另一个会话(会话由其名称​​和 ID标识),读取值,关闭其他会话并重新打开当前会话。它在技术上适用于PHP,但是在执行此操作时编写可靠的代码,因为会话问题很难调试。

这也是在多个客户端之间编写自己的对象共享机制而不是为此重用PHP's session featureDocs的好理由。

答案 1 :(得分:3)

多个客户端无法在会话对象中共享数据。如果要在客户端之间共享数据,通常会使用其他一些服务器端存储方式,例如:数据库。

答案 2 :(得分:2)

我为 PHP 应用程序编写了一个解决方案,主要解决了两类问题:

  • 如何在PHP进程之间共享数据/变量,托管在相同/不同的服务器上
  • 如何同步数据/变量中的读/写操作

我的项目托管在GitHub ANYEM Project

首先:使用命令行

启动 ANYEM_SERVER
php ANYEM/ANYEM_SERVER/anyem.app.server.impl/ServerImpl.php

现在,在您的PHP应用程序中,您可以执行以下操作:

<?php
// load server's connection configuration (ANYEM_SERVER IP and Port Number ...) 
$clientConnection    = ClientConnectionImpl::newClient();
// build a key for your variable that will be stored in server
// the key is composed on 3 Parts : [1] => URL, [2] => Variable Namespace, [3] => Variable Name
$identifier          = new ResourceIdentifierImpl("anyem.com", "anyemNameSpace", "a");

$a = 5;
$anyemClient         = new AnyemClientImpl($clientConnection, $identifier);
try {
    // if $a is reserved by another PHP Process, so this process
    // will sleep (1/10) seconds and retry the reservation of the resource
    // here, the max number of reservation attempts is 5, if reservation
    // fails, an Exception will be thrown
    $responseWrapper = $anyemClient->get($a, 5, 100000);
    // here we have reserved the variable $a, and we have the unserialized contents
    $a = $responseWrapper->getResource()->getData();
    // here, we update the contents, send it to ANYEM_SERVER and releasing the lock (we unreserve it)
    $anyemClient->put(++$a);
}
catch (Exception $e) {
    print $e->getMessage() . "\n";
    continue;
}

希望可以帮助某人:)

答案 3 :(得分:0)

我认为这个问题的最佳解决方案是使用数据库。创建一个表并存储在其中。当您只需要从表中读取数据时。在会话之间共享数据是快速简便的解决方案。