序列化PHP SOAPClient对象

时间:2011-03-23 14:34:57

标签: serialization soap soap-client php

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

我在实例化所有这些对象时会遇到很大的开销:在某些情况下,单行代码$object = new SoapClient($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;
}

这当然似乎是the way PHP recommends to do it

...然后像这样调用它......

$client = soap_client('servicename',$wsdl);
$client->MethodName($parameters);

然而,它似乎不起作用。

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

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

Fatal error: Uncaught SoapFault exception: [Client] Error finding "uri" property

显然,反序列化的对象与原始对象不同,这与对象序列化的工作方式不一致。

任何人都可以解释为什么我收到此错误?你能建议一种让它运作的方法,或者我可以坚持的另一种策略吗?

谢谢。

ps - 我试图解决这个问题,但没有快乐。

我已经尝试在options参数中指定URI(在PHP SOAP Client manual中指定),但它没有任何区别。但是无论如何它都没有必要,因为我正在使用WSDL。

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

2 个答案:

答案 0 :(得分:3)

内置的SOAP扩展是一个不可摧毁的二进制blob。很可能它并没有考虑到序列化。例如,它可能包含一个内部文件句柄,它不会在序列化/反序列化过程中存活。我建议你使用其他一些SOAP客户端,例如:

  • Zend_Soap,Zend Framework的一部分。您不需要在代码的任何其他区域使用Framework,并且可能删除大多数其他组件。但是,它似乎在封面下使用现有的SOAP扩展,因此它可能不适合序列化。
  • PEAR's SOAP经常被引用,虽然它有点旧。
  • NuSOAP最近已从死里复活,但所有在线文档似乎已经消失在zip文件中。

如果这些都不合适,请考虑在本地缓存WSDL文件,因为我不知何故预计会出现延迟。

答案 1 :(得分:2)

根据您对上一个答案的评论,最好的选择是使用Zend框架仅用于之前建议的soap,这将允许您继续使用php并且仍然具有更好的功能与zend。此外,您还可以利用Zend的其他功能,满足您的需求。

此示例可能对您有所帮助 http://blog.fedecarg.com/2009/02/15/building-a-web-service-client-using-the-zend-framework/