PHP Conference Japan 2024

SoapServer::setPersistence

(PHP 5, PHP 7, PHP 8)

SoapServer::setPersistence设置SoapServer持久化模式

描述

public SoapServer::setPersistence(int $mode): void

此函数允许在请求之间更改 SoapServer 对象的持久化状态。此函数允许利用 PHP 会话在请求之间保存数据。此方法仅在 SoapServer 使用 SoapServer::setClass() 导出函数后才有效。

注意:

SOAP_PERSISTENCE_SESSION 的持久化只使给定类的对象持久化,而不使类的静态数据持久化。在这种情况下,使用 $this->bar 而不是 self::$bar。

注意:

SOAP_PERSISTENCE_SESSION 会在请求之间序列化类对象上的数据。为了正确利用资源(例如 PDO),应该使用 __wakeup()__sleep() 魔术方法。

参数

mode

SOAP_PERSISTENCE_* 常量之一。

SOAP_PERSISTENCE_REQUEST - SoapServer 数据在请求之间不持久化。这是调用 setClass 后任何 SoapServer 对象的默认行为。

SOAP_PERSISTENCE_SESSION - SoapServer 数据在请求之间持久化。这是通过将 SoapServer 类数据序列化到 $_SESSION['_bogus_session_name'] 来实现的,因此必须在设置此持久化模式之前调用 session_start()

返回值

不返回任何值。

示例

示例 #1 SoapServer::setPersistence() 示例

<?php
class MyFirstPersistentSoapServer {
private
$resource; // (例如 PDO、mysqli 等)
public $myvar1;
public
$myvar2;

public function
__construct() {
$this->__wakeup(); // 我们调用我们的唤醒函数来处理启动我们的资源
}

public function
__wakeup() {
$this->resource = CodeToStartOurResourceUp();
}

public function
__sleep() {
// 我们确保在此处省略 $resource,以便我们的会话数据保持持久
// 否则会导致在下一个请求期间数据反序列化失败;因此,我们的 SoapObject 不会在请求之间持久。
return array('myvar1','myvar2');
}
}

try {
session_start();
$server = new SoapServer(null, array('uri' => $_SERVER['REQUEST_URI']));
$server->setClass('MyFirstPersistentSoapServer');
// setPersistence 必须在 setClass 之后调用,因为 setClass 的
// 行为在执行该方法时会设置 SESSION_PERSISTENCE_REQUEST。
$server->setPersistence(SOAP_PERSISTENCE_SESSION);
$server->handle();
} catch(
SoapFault $e) {
error_log("SOAP 错误: ". $e->getMessage());
}
?>

参见

添加注释

用户贡献的注释 6 条注释

csnaitsirch at web dot de
14 年前
我想举一个例子来说明如果您想在持久化模式下使用类,则命令的顺序。

<?php
// 1. 类定义或包含
class UserService
{
public function
__construct() { }
}

// 2. 在定义或包含类之后启动会话!
session_start();

// 3. 实例化服务器
$server = new SoapServer(null, array("something"));

// 4. 设置要使用的类
$server->setClass('UserService');

// 5. 设置持久化模式
$server->setPersistence(SOAP_PERSISTENCE_SESSION);

// 6. 处理请求
$server->handle();
?>
boogiebug at gmail dot com
16 年前
setPersistence 仅适用于服务类的单个实例。

要使用服务对象的多个实例,您需要将类实例化为对象,并使用未公开的 SoapServer 方法 - setObject() 将服务对象添加到 SoapServer 对象中,并使用 $_SESSION 处理服务对象的持久性。

例如

$ServiceObjects = array()
$ServiceObjects[0] = new ServiceClass1();
$ServiceObjects[1] = new ServiceClass2();
$ServiceObjects[2] = new ServiceClass3();

$_SESSION['ServiceClass1'] = $ServiceObjects[0];
$_SESSION['ServiceClass2'] = $ServiceObjects[1];
$_SESSION['ServiceClass3'] = $ServiceObjects[2];

...

$Servers = array();
for ( $i = 0; $i < count($ServiceObjects); $i++)
{
$s = new SoapServer($wsdl);
$s->setObject($ServiceObjects[$i]);


$Servers[] = $s;
}

...

$Servers[$i]->handle();



...
jan at pinna dot nl
16 年前
我发现同时使用两种模式(SOAP_PERSISTENCE_SESSION 和 SOAP_PERSISTENCE_REQUEST)不可行。因为无法同时工作,我开始尝试不同的设置,如下面的注释中所述,“...也使用 SOAP_PERSISTENCE_REQUEST 在请求之间保存对象”让我认为需要同时使用这两种模式。好吧,对其他人来说也许是必要的,但对我来说,这却让我沮丧了一整天(尝试各种会话操作等等)。
另外,如果持久性不起作用,请检查脚本中是否调用了 session_start(),并尝试不要调用两次或多次:它将无法工作……
jared at ws-db dot com
19 年前
我在让会话持久性 (SOAP_PERSISTENCE_SESSION) 工作时遇到了一些问题。在设置 session.auto_start=0,然后只在包含 SoapServer 的脚本中调用 session_start() 后,我终于让它工作了。也许这很明显,但我花了一点时间才弄清楚。

我只在 session.use_cookies=1 的情况下尝试过,因此,如果上述设置对您不起作用,请确保启用了 cookie,尽管它可能无需 cookie 即可工作。
cperez1000 at hotmail dot com
19 年前
始终记住在 handle 方法之前放置 "setPersistence" 方法,否则它将无法工作。这听起来很明显,但这仍然是一个非常常见的错误,因为没有显示任何错误。
doug dot manley at gmail dot com
16 年前
当使用 "SoapServer::setPersistence(SOAP_PERSISTENCE_SESSION)" 时,显然必须在任何 "session_*" 命令之前包含在 "SoapServer::setClass()" 中使用的类。

我使用 "__autoload()" 和大量的 "syslog()" 发现了这一点;它一直无法包含我用于 soap 服务器的类,但该类仅由页面本身引用,即使那样也仅用于为 soap 服务器设置类;我的任何代码都不会导致它自动加载。问题是我首先包含了我的会话处理代码。

如果在页面定义类定义之前启动会话,则持久性将无法发生。

顺序应该是
1. 包含用于 soap 服务器的类。
2. 启动会话。
3. 设置 soap 服务器。
4. 处理 soap 请求。
To Top