设为首页 收藏本站
查看: 749|回复: 0

[经验分享] PHP5的SOAP扩展

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-11-17 13:21:19 | 显示全部楼层 |阅读模式
简介
PHP的SOAP扩展可以用来提供和使用Web services。换句话说,PHP开发者可以利用这个PHP扩展来写他们自己的Web services,也可以写一些客户端来使用已有的Web services。
PHP5中的这个SOAP扩展目的是为了实现PHP对Web services的支持。与其它实现PHP对Web services的支持的方法不同,SOAP扩展是用C写的,因此它比其它方法(比较出名的Nusoap类)具有速度优势。
SOAP扩展支持以下规范。
* SOAP 1.1
* SOAP 1.2
* WSDL 1.1

SOAP扩展主要用来处理RPC形式的Web services。不过,你也可以使用文本形式的WSDL文件配合WSDL模式的服务端和客户端。
这个扩展使用 GNOME XML库来处理XML。
扩展中的类
这个扩展实现了6个类。
其中有三个高级的类,它们的方法很有用,它们是 SoapClient,SoapServer和SoapFault。
另外三个类除了构造器外没有其它别的方法,这三个是低级的类,它们是SoapHeader,SoapParam和SoapVar。

SoapClient类
这个类用来使用Web services。SoapClient类可以作为给定Web services的客户端。
它有两种操作形式:

* WSDL 模式
* Non-WSDL 模式

在WSDL模式中,构造器可以使用WSDL文件名作为参数,并从WSDL中提取服务所使用的信息。
non-WSDL模式中使用参数来传递要使用的信息。这个类有许多可以用来使用服务的有用的方法。其中SoapClient::__soapCall()是最重要的。这个方法可以用来调用服务中的某个操作。
SoapServer类
这个类可以用来提供Web services。与SoapClient类似,SoapServer也有两种操作模式:WSDL模式和non-WSDL模式。这两种模式的意义跟 SoapClient的两种模式一样。在WSDL模式中,服务实现了WSDL提供的接口;在non-WSDL模式中,参数被用来管理服务的行为。
在SoapServer类的众多方法中,有三个方法比较重要。它们是SoapServer::setClass(),SoapServer::addFunction()和SoapServer::handle()。
SoapServer::setClass()方法设定用来实现Web Service的类。SoapServer::setClass所设定的类中的所有公共方法将成为Web Services的操作(operation)。
SoapServer::addFunction()方法用来添加一个或多个作为Web Services操作(operation)的函数。
SoapServer:: handle()方法指示Web Service脚本开始处理进入的请求。Web Service脚本是用PHP脚本写的一个或多个SoapServer对象的实例。尽管你可以有不止一个的SoapServer对象,但通常的习惯是一个脚本只拥有一个SoapServer实例。在调用SoapServer::handle()方法之前,Web Service脚本会使用设置在SoapServer对象实例上的任何信息来处理进入的请求和输出的相应。
SoapFault类
这个类从Exception类继承而来,可以用来处理错误。SoapFault实例可以抛出或获取Soap错误的相关信息并按程序员的请求处理。
SoapHeader类
这个类可以用来描述SOAP headers。它只是一个只包含构造器方法的数据容器。
SoapParam类
SoapParam也是一个只包含构造器方法的数据容器。这个方法可以用来描述传递给Web services操作的参数。在non-WSDL模式中这是一个很有用的类,可以用来传递所期望格式的参数信息。
SoapVar类
SoapVar也是一个只包含构造器的低级类,与SoapHeader和SoapParam类相似。这个类可以用来给一个Web services操作传递编码参数。这个类对non-WSDL中传递类型信息是非常有用的。
WSDL VS. non-WSDL模式
Web Services有两种实现模式:契约先行(Contract first)模式和代码先行(Code first)模式。
契约先行模式使用了一个用XML定义的服务接口的WSDL文件。WSDL文件定义了服务必须实现或客户端必须使用的接口。SoapServer和SoapClient的WSDL模式就基于这个概念。
在代码先行模式中,首先要先写出实现服务的代码。然后在大多数情况下,代码会产生一个契约,换种说法,一个WSDL。接着客户端在使用服务的时候就可以使用那个WSDL来获得服务的接口。尽管如此,PHP5的扩展并没有从代码输出一个WSDL的规定,考虑到这种情况,可以在non-WSDL模式下使用 SoapServer和SoapClient。
SOAP扩展与Hello World
这一节介绍如何使用WSDL模式和non-WSDL模式来实现服务和客户端。相对而言,使用WSDL模式来实现服务和客户端会比较容易,假定已经有一个定义了接口的WSDL文件。(淡水对WSDL还比较陌生,就只关注non-wsdl模式了。)
如何使用WSDL模式实现一个Web Service。
在这个Hello World例子的服务中有一个被命名为greet的操作。这个操作有一个字符串形式的名字并返回一个字符串形式的greeting。所用到的WSDL如下:
<wsdl:definitions
   xmlns:impl='http://wso2.org/wsf/php/helloService'
   xmlns:intf='http://wso2.org/wsf/php/helloService'
   xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
   xmlns:wsdlsoap='http://schemas.xmlsoap.org/wsdl/soap/'
   xmlns:xsd='http://www.w3.org/2001/XMLSchema'
   targetNamespace='http://wso2.org/wsf/php/helloService'>  
  <wsdl:types>
    <schema elementFormDefault='qualified'
       xmlns:impl='http://wso2.org/wsf/php/helloService'
       xmlns:intf='http://wso2.org/wsf/php/helloService'
       xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
       xmlns=&quot;http://www.w3.org/2001/XMLSchema&quot;
       targetNamespace='http://wso2.org/wsf/php/helloService' >
      <element name='greet'>
        <complexType>
          <sequence>
            <element name='name' type='xsd:string' />
          </sequence>
        </complexType>
      </element>
      <element name='greetResponse'>
        <complexType>
          <sequence>
            <element name='greetReturn' type='xsd:string' />
          </sequence>
        </complexType>
      </element>
    </schema>
  </wsdl:types>
  <wsdl:message name='greetRequest'>
    <wsdl:part name='parameters' element='impl:greet' />
  </wsdl:message>
  <wsdl:message name='greetResponse'>
    <wsdl:part name='parameters' element='impl:greetResponse' />
  </wsdl:message>
  <wsdl:portType name='helloService'>
    <wsdl:operation name='greet'>
      <wsdl:input name='greetRequest' message='impl:greetRequest' />
      <wsdl:output name='greetResponse' message='impl:greetResponse' />
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name='helloServiceSoapBinding' type='impl:helloService'>
    <wsdlsoap:binding transport='http://schemas.xmlsoap.org/soap/http' style='document' />
    <wsdl:operation name='greet'>
      <wsdlsoap:operation soapAction='helloService#greet' />
      <wsdl:input name='greetRequest'>
        <wsdlsoap:body use='literal' />
      </wsdl:input>
      <wsdl:output name='greetResponse'>
        <wsdlsoap:body use='literal' />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name='helloService'>
    <wsdl:port binding='impl:helloServiceSoapBinding' name='helloService'>
      <wsdlsoap:address location='http://localhost/hello/hello_service_wsdl.php' />
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>WSDL模式服务
下面是WSDL模式的服务所使用的SOAP扩展API代码:
function greet($param) {
$retval = 'Hello '.$param->name;
$result = array(‘greetReturn’ => $retval);
return $result;
}
$server = new SoapServer(‘hello.wsdl’);
$server->addFunction(‘greet’);
$server->handle();
?>
在这个服务的实现过程中,函数实现了WSDL所定义的服务操作greet,greet操作有一个WSDL指定的参数,按照greet操作的语义,这个参数是一个用户的名字。最后handle调用了触发处理请求的服务对象。
WSDL模式客户端
客户端代码如下
try {
$client = new SoapClient('hello.wsdl');
$result = $client->__soapCall(‘greet’, array(array(‘name’ => ‘Sam’)));
printf(“Result = %s”, $result->greetReturn);
} catch (Exception $e) {
printf(“Message = %s”,$e->__toString());
}
?>
客户端代码中,首先创建一个使用WSDL文件作参数的SoapClient实例。接着__soapCall()调用作为参数传入它的操作,也就是greet和传入操作的参数。
请求和响应
当你将上述的PHP脚本放在你web服务器目录下的文档中,并利用WEB浏览器或在PHP解析器的命令行调用脚本,客户端发送一个SOAP请求到服务端脚本,服务端将向客户端发送一个SOAP响应来响应客户端的请求。
下面是客户端所发送的SOAP请求:
<?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?>   
   <SOAP-ENV:Envelope xmlns:SOAP-ENV=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;                     
                                 xmlns:ns1=&quot;http://wso2.org/wsf/php/helloService&quot;>   
    <SOAP-ENV:Body>
    <ns1:greet>
    <ns1:name>Sam</ns1:name>
    </ns1:greet>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>下面是服务端响应上诉请求而发送的SOAP响应:
<?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?>
   <SOAP-ENV:Envelope xmlns:SOAP-ENV=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;
                     xmlns:ns1=&quot;http://wso2.org/wsf/php/helloService&quot;>
      <SOAP-ENV:Body>
         <ns1:greetResponse>
            <ns1:greetReturn>Hello Sam</ns1:greetReturn>
         </ns1:greetResponse>
      </SOAP-ENV:Body>
   </SOAP-ENV:Envelope>上面的SOAP消息都是利用WSDL模式的服务端和客户端来获取的。也可以利用non-WSDL模式的服务端和客户端来产生与上面相同的SOAP消息。但是,PHP代码必须有一点改变。下一节会说明如何使用non-WSDL模式。
non-WSDL模式服务端
<?php
function greet($param) {   
    $retval = 'Hello '.$param;
    return new SoapParam($retval, 'greetReturn');
}

$server = new SoapServer(null, array('uri' => 'http://wso2.org/wsf/php/helloService'));

$server->addFunction('greet');
$server->handle();
?>在non -WSDL模式中,想WSDL模式一样首先实现greet函数的功能,但是函数实现的方式跟WSDL模式稍稍有所不同。在non-WSDL模式中,我们必须返回一个SoapParam对象作为响应,而不是一个数组。创建服务时,第一个参数设为null,说明没有提供WSDL;接着传递一个选项作为参数,这个选项参数是服务的URI。最后像WSDL模式一样调用剩下的方法。
non-WSDL模式客户端
<?php
try {
    $client = new SoapClient(null,   
    array('location' => 'http://localhost/hello/hello_service_nonwsdl.php',
    'uri' => 'http://wso2.org/wsf/php/helloService'));   
    $result =  $client->__soapCall('greet', array(new SoapParam('Sam', 'name')));
    printf(&quot;Result = %s&quot;, $result);
} catch (Exception $e) {
    printf(&quot;Message = %s&quot;,$e->__toString());
}
?>在non-WSDL模式中,因为没有使用WSDL,传递了一个包含服务所在位置和服务URI的参数数组作为参数。然后象WSDL模式中一样调用__soapCall()方法,但是使用了SoapParam类用指定&#26684;式打包参数。返回的结果将获取greet中的响应。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-140349-1-1.html 上篇帖子: [转]Eclipse+PHPEclipse+DBG的PHP开发调试环境的安装与配置 下篇帖子: 为PHP开发C++扩展
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表