序列化 PHP SOAPClient 对象
我正在编写一个 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;
}
: net/manual/en/language.oop5.serialization.php" rel="nofollow">PHP 推荐的方式。
...然后这样称呼它...
$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 中指定的手册),但这没有任何区别。但无论如何都没有必要,因为我正在使用 WSDL。
我还尝试简单地将对象复制到 $_SESSION
,而不使用 serialize()
和 deserialize()
,但这具有完全相同的效果影响。
I'm writing a PHP application which uses a number of SOAP web services to gather data.
I'm getting significant overheads in instantiating all those objects: in some cases a single line of code $object = new SoapClient($wsdl);
can take over three seconds. It obviously only takes a few of those to make a web page feel really slow.
To speed things up a bit, I figured I'd serialise the objects and store them in the session (or somewhere similar), so I wrote the following function:
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;
}
That certainly seems to be the way PHP recommends to do it.
...and then calling it like this...
$client = soap_client('servicename',$wsdl);
$client->MethodName($parameters);
However, it doesn't seem to work.
The first time you run it, it works (ie the object is created and a serialised copy is made, and the method call works fine). However the second time you run it, it fails.
The object appears to serialise and de-serialise correctly, but when you try to execute a SOAP call on the de-serialised object, it throws the following error:
Fatal error: Uncaught SoapFault exception: [Client] Error finding "uri" property
Clearly the de-serialised object is not the same as the original object, which is at odds with how object serialisation is supposed to work.
Can anyone explain why I'm getting this error? Can you suggest a way to get it working, or an alternative strategy that I could be persuing?
Thank you.
ps - I've tried to work around the problem, but no joy.
I've tried specifying the URI in the options parameter (as specified in the PHP SOAP Client manual), but it didn't make any difference. But it shouldn't be necessary anyway, as I'm using a WSDL.
I've also tried simply copying the object to $_SESSION
, without using serialize()
and deserialize()
, but that has exactly the same effect.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
内置的 SOAP 扩展是一个无法调试的可怕的二进制 blob。它很可能不是在构建时考虑到序列化的。例如,它可能包含无法在序列化/反序列化过程中幸存的内部文件句柄。我强烈建议您使用其他 SOAP 客户端,例如:
如果这些都不合适,请考虑在本地缓存 WSDL 文件,因为我以某种方式预计这就是延迟所在。
The built-in SOAP extension is an undebuggable binary blob of horrors. It's very likely that it was not built with serialization in mind. For example, it could contain an internal filehandle that won't survive the serialize/unserialize process. I urge you to use some other SOAP client, such as:
If none of these are suitable, consider caching the WSDL file locally, as I somehow expect that's where the delay is.
根据您对上一个答案的评论,最好的选择是按照之前的建议仅将 Zend 框架用于肥皂,这将允许您继续使用 php,并且仍然可以使用 zend 获得更好的功能。如果您的需求增加,您还可以使用 Zend 的其他功能。
这个例子可能对你有帮助
http:// blog.fedecarg.com/2009/02/15/building-a-web-service-client-using-the-zend-framework/
As per your comments to the previous answer, the best option would be to use Zend framework only for soap as suggested before, this will allow you to keep using php and still have a better functionality with zend. Also you can utilize other features of Zend incase your requirements increases.
This example might help you
http://blog.fedecarg.com/2009/02/15/building-a-web-service-client-using-the-zend-framework/