5

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

客户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

4 回答 4

4

先回答你最后一个问题:

您链接的Session PgSQL Docs是PostgreSQL Session Save Handler。它是一个会话保存处理程序,您可以配置为使用它来代替默认的会话保存处理程序。PHP 中的默认会话保存处理程序是将会话存储到磁盘 ( files)。如果您使用 PostgreSQL 会话的保存处理程序,则会将其保存到 PostgreSQL 数据库中 ( pgsql)。

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

那么回答你的第一个问题:

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

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

这通常也是在多个客户端之间编写自己的对象共享机制而不是为此重新使用PHP 的会话功能Docs的一个很好的理由。

于 2013-03-31T11:16:59.893 回答
3

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

于 2013-03-31T08:11:04.000 回答
2

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

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

我的项目托管在 GitHub ANYEM 项目中

首先:使用命令行启动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;
}

希望可以帮助某人:)

于 2015-07-18T11:28:23.333 回答
0

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

于 2018-01-18T17:17:40.373 回答