我正在编写一个PHP应用程序,它使用一些SOAP Web服务来收集数据。序列化一个PHP SOAPClient对象
我在实例化所有这些对象时收到了大量的开销:在某些情况下,一行代码$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 - 我试着解决这个问题,但没有喜悦。
我试过在选项参数中指定URI(如PHP SOAP Client manual中指定的那样),但它没有任何区别。但是,无论如何,因为我正在使用WSDL,所以它不是必需的。
我也尝试过简单地将对象复制到$_SESSION
,而不使用serialize()
和deserialize()
,但这种效果完全相同。
感谢您的答复。我已经做了一些进一步的调查,看起来像你的分析是现实的 - 序列化的字符串几乎没有用于重建对象;它几乎没有任何内容,所以解串行不起来也就不足为奇了。我会研究其他的选择,但是PHP SOAP已经很好地融入到了我们的应用程序中,所以切换起来可能太痛苦了。我们已经研究过WSDL缓存;它迄今还没有工作,但我会重新访问它,因为我认为我们之前没有做到。 – Spudley 2011-03-24 11:05:57
而不是学习另一个肥皂的扩展,我会建议寻找wsdl缓存。除非你有特定的功能。 – denormalizer 2011-05-31 07:17:30
@Charles使用Zend_Soap_Client不起作用,因为它包装了一个[扩展的SoapClient](http://framework.zend.com/apidoc/1.11/db_Soap_Client_Common.html#%5CZend_Soap_Client_Common)类。将此存储到(Zend_)缓存或(Zend_)会话中也会导致反序列化问题,除非您之前没有使用客户端。由于Zend_Soap_Client延迟加载底层的SoapClient,这可能会导致应用程序中出现未知的副作用。 – Partyschaum 2012-02-03 11:33:17