- 本文地址: https://www.laruence.com/2010/03/26/1365.html
- 转载请注明出处
在PHP的Soap Extension中, 对于SoapServer来说, 并没有方法可用得到/处理客户端发送的SoapHeader信息.
网上也有很多人认为, 只能通过读取POST过来的请求XML文件, 分析, 才能得到客户端发送过来的SoapHeader.
但, 其实在SoapServer端, 其实是有一种办法, 可用把SoapHeader当作一个请求来处理, 从而获取到客户端提交的SoapHeader信息.
假设客户端代码如下:
<?php /* * 保存用户名和密码的载体 */ class SoapUserInfo { /** * @var char $name */ public $name; /** * @var char $password */ public $password; public function __construct($l, $p) { $this->Password = $p; $this->Username = $l; } } ?>
然后客户端生成SoapHeader
<?php $soap_header = new SoapHeader("http://www.laruence.com", 'Authorise' , new SoapUserInfo('laruence', 'password'), false, SOAP_ACTOR_NEXT); ?>
也许细心的同学会注意到第4个参数FALSE和第5个参数SOAP_ACTOR_NEXT, 这是什么呢? 我最后再讲.
然后, 创建客户端, 绑定SoapHeader
<?php $client = new SoapClient($wsdl); $client->__setSoapHeaders(array($soap_header)); $client->__soapCall('request', array()); ?>
现在, 客户端已经发起了请求, 请求中也包含了SoapHeader, 其中有了我们验证需要的用户名/密码信息.
那么, 在服务端, 该如何做呢?
<?php $server = new SoapServer('laruence.wsdl'); $server->setClass('InterfaceClass'); $server->handle(); ?>
关键的地方就在, 服务端接收请求以后, 会实例化一个处理类, 然后分析SoapHeader, 接着就会调用InterfaceClass::Authorise这个方法(Authorise是我们请求头中的变量名), 所以, 我们就可用在InterfaceClass类中, 定义个Authorise方法, 并在这个方法中对SoapHeader中的信息做验证.
然后, 请求体(Soap body)中的方法被调用, 因为不论Authorise方法返回什么(除非exit), 请求体中的方法一定会被调用, 所以要寻找个变量记录验证的结果.
<?php class InterfaceClass { /** * @var bool $authorized */ private $authorized = FALSE; /* * Authentication function * * @param string username * @param string password */ public function Authentication($username, $password) { $this->authorized = validateUser($username, $password); } /* * Test method */ public function request(){ if ($this->authorized) { //验证成功, 继续处理. } else { //验证失败, 拒绝请求. } } } ?>
当然, 对于网上说的另外一种方法, 通过分析请求的XML文件, 也可以:
<?php class InterfaceClass { /** * @var bool $authorized */ private $authorized = FALSE; function __construct() { $xml = file_get_contents('php://input'); //分析xml, 获得SoapHeader数据, 验证 } } ?>
Must Understand
这个参数指明了, 是否服务端必须要了解SoapHeader, 如果这个参数为真, 而服务端并不能识别响应的Header, 则会引发一个Soap Fault(Header not understood).
SOAP_ACTOR_NEXT
actor指明了SoapHeader要传递给谁, 被谁处理.
SOAP_ACTOR_NEXT的意思就是, 下一个接受到这个请求头的Service, 在本文的例子中只有一个Server,当然也就没有关系了.
在SoapServer的构造函数中, 我们可以指明一个Server的Actor, 比如:
<?php $server = new SoapServer($wsdl, array('actor' => 'laruence')); ?>
这样, 我们就可以在Client的SoapHeader中, 通过设置actor是laruence, 来让指定的Server来获得我们设置的头部的信息.
I like reading an article that can make men and women think.
Also, thanks for allowing for me to comment!
May I simply just say what a relief to uncover somebody who trtuly understasnds
what they arre discussing on the net. You actually underdtand how to
bring a problem to light and make it important. More people really need to
look at this and understand this side of the story.
I can’t believe you’re not more popular given that you certainly have the gift.
Thank you for any other excellent article. Where else could anyone
get that type of information in such an ideal method of
writing? I’ve a presentation subsequent week, and I’m on the look for such info.
Le immagini generalmente sono molto curate per quanto riguarda gli aspetti formali
ed estetici (luce, composizione, pose dei soggetti), ma la resa un po
statica, in quanto non essendo dei fotomodelli professionisti,
i soggetti fanno fatica a rimanere rilassati e naturali di fronte
alla macchina fotografica. Mainly it covers the actual Microsoft windows and also the Microsof company servers.
Organizzare un matrimonio molto complesso,
scegliere un ristorante, un vestito, valutare le decorazioni
ed orientarsi tra le centinaia di fotografi matrimonio.
鸟哥设置header验证时SoapHeader里的namespace是必须要写的吗
The age of empires online weapon upgrades doesn’t quite do it for me, I mean come on solely four. You should examine Extreme Niche Empires should you be currently never making at least a number of thousand dollars 30 days online. Leading environmental organizations have received significant payoffs from BP in recent years.
If you are newbie to domains names then you are certainly a Domainbie
想问一下,客户端的SoapHeader中请求的Authorise这个变量对应的是服务端的一个验证方法,如果这个方法我在wsdl文档中不提现,服务端有,那么服务端能获取header过来的验证数据吗? 我在wsdl文件中定义了Authorise的情况下是可以取到验证数据的,但是不定义的情况下就不行了。
//认证
$h = new SoapHeader(‘urn:oufei’, ‘auth’, ‘123456’, false, SOAP_ACTOR_NEXT);
$result = $soapClient-> __setSoapHeaders( array($h) );
一直没调用auth方法
function auth($a){
if($a != ‘123456789’){
throw new SoapFault(‘server’, “认证失败!”);
}
}
The incestuous relationship between government and big business thrives in the dark….
Hello there, just became aware of your blog through Google, and found that it is truly informative. I’m gonna watch out for brussels. I’ll appreciate if you continue this in future. Many people will be benefited from your writing. Cheers!…
Thanks for sharing this script..
I had a dream to begin my organization, however I didn’t have got enough of cash to do that. Thank heaven my close mate told to take the home loans. Thus I received the small business loan and made real my dream.
webservice 超时,有什么好的解决方案吗?
补充一点, 可以通过GLOBALS:HTTP_RAW_POST_DATA 在Server端拿到
@54chen 那看应用环境了, 存在必有其合理性么.
soap使用起来感觉太慢了,我现在更喜欢ice啥的直接走底层网络