Serialization 序列化PHP SOAPClient对象

Serialization 序列化PHP SOAPClient对象,serialization,soap,soap-client,php,Serialization,Soap,Soap Client,Php,我正在编写一个PHP应用程序,它使用许多SOAP web服务来收集数据 在实例化所有这些对象时,我的开销很大:在某些情况下,一行代码$object=newsoapclient($wsdl)可能需要三秒以上。很明显,只需要其中的一小部分就可以让网页感觉非常慢 为了加快速度,我想我应该序列化对象并将它们存储在会话中(或类似的地方),因此我编写了以下函数: function soap_client($name,$wsdl) { if (!isset($_SESSION['soapobjects

我正在编写一个PHP应用程序,它使用许多SOAP web服务来收集数据

在实例化所有这些对象时,我的开销很大:在某些情况下,一行代码
$object=newsoapclient($wsdl)可能需要三秒以上。很明显,只需要其中的一小部分就可以让网页感觉非常慢

为了加快速度,我想我应该序列化对象并将它们存储在会话中(或类似的地方),因此我编写了以下函数:

function soap_client($name,$wsdl) {
    if (!isset($_SESSION['soapobjects'][$name])) {
        $client = new SoapClient($wsdl, array('trace' => 1));
            $_SESSION['soapobjects'][$name]=serialize($client);
        } else {
            $client = unserialize($_SESSION['soapobjects'][$name]);
        }
    return $client;
}
看起来确实如此

…然后像这样称呼它

$client = soap_client('servicename',$wsdl);
$client->MethodName($parameters);
然而,它似乎不起作用

第一次运行它时,它工作(即创建了对象并创建了序列化副本,并且方法调用工作正常)。但是,第二次运行它时,它失败了

对象似乎可以正确序列化和反序列化,但当您尝试对反序列化对象执行SOAP调用时,它会抛出以下错误:

Fatal error: Uncaught SoapFault exception: [Client] Error finding "uri" property
显然,反序列化对象与原始对象不同,这与对象序列化的工作方式不一致

有人能解释我为什么会犯这个错误吗?你能建议一个让它工作的方法,或者一个我可以尝试的替代策略吗

多谢各位

我试着解决这个问题,但没有乐趣

我尝试在options参数中指定URI(如中所指定),但没有任何区别。但无论如何,这应该不是必需的,因为我使用的是WSDL


我还尝试过简单地将对象复制到
$\u SESSION
,而不使用
serialize()
deserialize()
,但效果完全相同。

内置的SOAP扩展是一个不可调试的二进制恐惧。很可能它的构建没有考虑序列化。例如,它可能包含一个内部文件句柄,在序列化/取消序列化过程中无法生存。我建议您使用其他一些SOAP客户端,例如:

  • ,是Zend框架的一部分。您不需要在代码的任何其他区域使用该框架,并且可能可以删除大多数其他组件。然而,它似乎在幕后使用了现有的SOAP扩展,因此它可能不是序列化的好候选
  • 经常被引用,尽管它有点旧
  • 虽然所有的在线文档似乎都消失在zip文件中,但最近已经死而复生

如果没有一个是合适的,考虑在本地缓存WSDL文件,因为我在某种程度上期望延迟是在哪里。

< P>根据您对前一个答案的评论,最好的选择是使用ZAND框架,之前只建议使用SOAP,这将允许您继续使用PHP,并且仍然具有更好的ZEN功能。此外,如果您的需求增加,您还可以利用Zend的其他功能

这个例子可能会对你有所帮助

谢谢您的回复。我做了一些进一步的调查,看起来你的分析是正确的——序列化的字符串对于重建对象几乎是无用的;它实际上什么都没有,所以反序列化不起作用也就不足为奇了。我将研究其他替代方案,但PHP SOAP在我们的应用程序中已经非常成熟,因此切换起来可能太痛苦了。我们已经研究了WSDL缓存;到目前为止,它还没有起作用,但我将再次访问它,因为我认为我们之前没有正确地使用它。与其学习另一个soap扩展,我建议研究wsdl缓存。当然,除非有您想要的特定功能。@Charles使用Zend_Soap_客户端也不起作用,因为它包装了一个类。将其存储到(Zend_)缓存或(Zend_)会话中也会导致反序列化问题,除非您以前没有使用过客户端。由于Zend_Soap_Client延迟加载底层的SoapClient,这可能会在应用程序中导致不可预见的副作用。谢谢,@Partyschaum,我已将这些信息集成到我的答案中。