宝马娱乐在线城-宝马娱乐在线

来自 互联网络 2019-10-01 21:34 的文章
当前位置: 宝马娱乐在线城 > 互联网络 > 正文

PHP教程:WebService最常用的两种方法

[ Web Service介绍 ]

 国内用PHP写WebService的真的很少,网上资料也没多少,公司的项目开发过程中,经历了不少这方面的东西,写出来以供大家参考(谢谢老农提供的WSDL和程序文件)

  Web Service就是为了异构系统的通信而产生的,它基本的思想就是使用基于XML的HTTP的远程调用提供一种标准的机制,而省去建立一种新协议的需求。目前进行Web Service通信有两种协议标准,一种是XML-RPC,另外一种是SOAP。XML-RPC比较简单,出现时间比较早,SOAP比较复杂,主要是一些需要稳定、健壮、安全并且复杂交互的时候使用。

  客户端

  PHP中集成了XML-RPC和SOAP两种协议的访问,都是集中在xmlrpc扩展当中。另外,在PHP的PEAR中,不管是PHP 4还是PHP 5,都已经默认集成了XML-RPC扩展,而且该扩展跟xmlrpc扩展无关,能够独立实现XML-RPC的协议交互,假如没有xmlrpc扩展,建议使用PEAR::XML-RPC扩展。

  代码:

  我们这里主要是以XML-RPC来简单描述Web Service的交互过程,部分内容来自PHP手册,更具体内容,建议参考手册。

01.  
  02.header ( "Content-Type: text/html; charset=utf-8" );
  03./*
  04.* 指定WebService路径并初始化一个WebService客户端
  05.*/
  06.$ws ="http://soap/soapCspMessage.php?wsdl";
  07.$client =new SoapClient ( $ws, array ('trace' => 1, 'uri' => 'http://www.zxsv.com/SoapDiscovery/' ) );

  [ 安装xmlrpc扩展 ]

  08./*
  09.* 获取SoapClient对象引用的服务所提供的所有方法
  10.*/
  11.echo ("SOAP服务器提供的开放函数:");
  12.echo ('
');
  13.var_dump ( $client->__getFunctions () );
  14.echo ('
');
  15.echo ("SOAP服务器提供的Type:");
  16.echo ('
');
  17.var_dump ( $client->__getTypes () );
  18.echo ('
');
  19.echo ("执行GetGUIDNode的结果:");
  20.//$users = $client->GetUsers();
  21.//var_dump($HelloWorld );
  22.$parameters =array('uname'=>'zxsv',"upassword"=>'123');

  假如你的系统中没有安装xmlrpc的php扩展,那么请正确安装。

  23.$out = $client->HelloWorld($parameters);
  24.$datadb = $out->HelloWorldResponse;
  25.var_dump($out);
  26.?>

  在Windows平台下,首先把PHP安装目录下的扩展php_xmlrpc.dll放到C:Windows或者C:Winnt目录下,(PHP4的扩展在C:phpextensions目录中,PHP5的扩展在C:phpext目录中),同时在C:Windowsphp.ini或者C:Winntphp.ini中把extension=php_xmlrpc.dll前面的分号";"去掉,然后重启Web服务器后查看phpinfo()有没有XML-RPC项目就能够确定是否已经正确安装xmlrpc扩展。

  服务端

  在Unix/Linux平台下,假如没有安装xmlrpc扩展,请在重新编译PHP,在configure的时候请加入 --with-xmlrpc 选项,然后查看phpinfo()看是否正常安装xmlrpc。

  代码:

  (注重:以下操作都是建立在xmlrpc扩张正常安装前提下,请务必正确安装。)

 

  [ XML-RPC工作原理 ]

01.  
  02.class Member
  03.{
  04.public $UserId;
  05.public $Name;
  06.public function __construct($parmas){
  07.$this->UserId = $parmas[0];
  08.$this->Name = $parmas[1];
  09.}
  10.}
  11.$servidorSoap =new SoapServer('testphp.XML',array('uri' => 'http://www.TestPHP.com/','encoding'=>'utf-8','soap_version' => SOAP_1_2 ));
  12.$servidorSoap->setClass(Testphp);
  13.$servidorSoap->handle();
  14.class Testphp {
  15.public function HelloWorld($uid){
  16.return array('HelloWorldResult'=>"mystring".$uid->{'uname'}.' and '.$uid->{'upassword'});
  17.}
  18.public function GetMember($uid){
  19.$s=array();
  20.for($i=0;$i<$uid->{'uid'};$i++){
  21.$s[] =&new Member(array($i, $uid->{'uname'}.'我测试'.$i));
  22.}
  23.return array('GetMemberResult'=>$s);
  24.}
  25.}
  26.?>

  XML-RPC大致就是整个过程就是使用XML来进行通信。首先构造一个RPC 服务器端用来出来从RPC客户端传递过来的使用XML封装的请求,并且把处理结果通过XML的形式返回给RPC客户端,客户端就去分析XML获取自己需要的数据。

  到这里应该都看的懂吧

  XML-RPC的服务器端必须有现成的函数提供给客户端调用,并且客户端提交的请求中的函数和方法必须和服务器端的一致,否则将无法获取所需要的结果。

  下面是WSDL文件

  下面我进行简单的代码来描述整个过程。

  代码:

  [ XML-RPC实践 ]

 

  服务器端使用xmlrpc_server_create函数产生一个服务器端,然后把需要需要暴露的RPC调用接口进行注册,接受RPC客户端POST过来的XML数据,然后进行处理,处理结果通过XML的形式显示给客户端。

001.<?xml version="1.0" encoding="utf-8"?>
002.<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://www.TestPHP.com/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="http://www.TestPHP.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"&gt;
003.<wsdl:types>
004.<s:schema elementFormDefault="qualified" targetNamespace="http://www.TestPHP.com/"&gt;
005.<s:element name="HelloWorld">
006.<s:complexType>
007.<s:sequence>
008.<s:element minOccurs="0" maxOccurs="1" name="uname" type="s:string"/>
009.<s:element minOccurs="0" maxOccurs="1" name="upassword" type="s:string"/>
010.</s:sequence>
011.</s:complexType>
012.</s:element>
013.<s:element name="HelloWorldResponse">
014.<s:complexType>
015.<s:sequence>
016.<s:element minOccurs="0" maxOccurs="1" name="HelloWorldResult" type="s:string"/>
017.</s:sequence>
018.</s:complexType>
019.</s:element>
020.<s:element name="GetMember">
021.<s:complexType>
022.<s:sequence>
023.<s:element minOccurs="1" maxOccurs="1" name="uid" type="s:int"/>
024.<s:element minOccurs="0" maxOccurs="1" name="uname" type="s:string"/>
025.</s:sequence>
026.</s:complexType>
027.</s:element>
028.<s:element name="GetMemberResponse">
029.<s:complexType>
030.<s:sequence>
031.<s:element minOccurs="0" maxOccurs="1" name="GetMemberResult" type="tns:ArrayOfMember"/>
032.</s:sequence>
033.</s:complexType>
034.</s:element>
035.<s:complexType name="ArrayOfMember">
036.<s:sequence>
037.<s:element minOccurs="0" maxOccurs="unbounded" name="Member" nillable="true" type="tns:Member"/>
038.</s:sequence>
039.</s:complexType>
040.<s:complexType name="Member">
041.<s:sequence>
042.<s:element minOccurs="1" maxOccurs="1" name="UserId" type="s:int"/>
043.<s:element minOccurs="0" maxOccurs="1" name="Name" type="s:string"/>
044.</s:sequence>
045.</s:complexType>
046.</s:schema>
047.</wsdl:types>
048.<wsdl:message name="HelloWorldSoapIn">
049.<wsdl:part name="parameters" element="tns:HelloWorld"/>
050.</wsdl:message>
051.<wsdl:message name="HelloWorldSoapOut">
052.<wsdl:part name="parameters" element="tns:HelloWorldResponse"/>
053.</wsdl:message>
054.<wsdl:message name="GetMemberSoapIn">
055.<wsdl:part name="parameters" element="tns:GetMember"/>
056.</wsdl:message>
057.<wsdl:message name="GetMemberSoapOut">
058.<wsdl:part name="parameters" element="tns:GetMemberResponse"/>
059.</wsdl:message>
060.<wsdl:portType name="TestPHPSoap">
061.<wsdl:operation name="HelloWorld">
062.<wsdl:input message="tns:HelloWorldSoapIn"/>
063.<wsdl:output message="tns:HelloWorldSoapOut"/>
064.</wsdl:operation>
065.<wsdl:operation name="GetMember">
066.<wsdl:input message="tns:GetMemberSoapIn"/>
067.<wsdl:output message="tns:GetMemberSoapOut"/>
068.</wsdl:operation>
069.</wsdl:portType>
070.<wsdl:binding name="TestPHPSoap" type="tns:TestPHPSoap">
071.<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/&gt;
072.<wsdl:operation name="HelloWorld">
073.<soap:operation soapAction="http://www.TestPHP.com/HelloWorld"   />
074.<wsdl:input>
075.<soap:body use="literal"/>
076.</wsdl:input>
077.<wsdl:output>
078.<soap:body use="literal"/>
079.</wsdl:output>
080.</wsdl:operation>
081.<wsdl:operation name="GetMember">
082.<soap:operation soapAction="http://www.TestPHP.com/GetMember"  />
083.<wsdl:input>
084.<soap:body use="literal"/>
085.</wsdl:input>
086.<wsdl:output>
087.<soap:body use="literal"/>
088.</wsdl:output>
089.</wsdl:operation>
090.</wsdl:binding>
091.<wsdl:binding name="TestPHPSoap12" type="tns:TestPHPSoap">
092.<soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/&gt;
093.<wsdl:operation name="HelloWorld">
094.<soap12:operation soapAction="http://www.TestPHP.com/HelloWorld"  />
095.<wsdl:input>
096.<soap12:body use="literal"/>
097.</wsdl:input>
098.<wsdl:output>
099.<soap12:body use="literal"/>
100.</wsdl:output>
101.</wsdl:operation>
102.<wsdl:operation name="GetMember">
103.<soap12:operation soapAction="http://www.TestPHP.com/GetMember"  />
104.<wsdl:input>
105.<soap12:body use="literal"/>
106.</wsdl:input>
107.<wsdl:output>
108.<soap12:body use="literal"/>
109.</wsdl:output>
110.</wsdl:operation>
111.</wsdl:binding>
112.<wsdl:service name="TestPHP">
113.<wsdl:port name="TestPHPSoap" binding="tns:TestPHPSoap">
114.<soap:address location="http://soap/goodwsdl/testphp.php"/&gt;
115.</wsdl:port>
116.<wsdl:port name="TestPHPSoap12" binding="tns:TestPHPSoap12">
117.<soap12:address location="http://soap/goodwsdl/testphp.php"/&gt;
118.</wsdl:port>
119.</wsdl:service>
120.</wsdl:definitions>

  代码如下: rpc_server.php

 

<?php
/**
* 函数:提供给RPC客户端调用的函数
* 参数:
* $method 客户端需要调用的函数
* $params 客户端需要调用的函数的参数数组
* 返回:返回指定调用结果
*/
function rpc_server_func($method, $params) {
$parameter = $params[0];
if ($parameter == "get")
{
$return = 'This data by get method';
}
else
{
$return = 'Not specify method or params';
}
return $return;
}

  这里有返回的两个字段,一个是返回字符串,这个很好理解

//产生一个XML-RPC的服务器端
$xmlrpc_server = xmlrpc_server_create();

 

//注册一个服务器端调用的方法rpc_server,实际指向的是rpc_server_func函数
xmlrpc_server_register_method($xmlrpc_server, "rpc_server", "rpc_server_func");

01.<s:element name="HelloWorld">
02.<s:complexType>
03.<s:sequence>
04.<s:element minOccurs="0" maxOccurs="1" name="uname" type="s:string"/>
05.<s:element minOccurs="0" maxOccurs="1" name="upassword" type="s:string"/>
06.</s:sequence>
07.</s:complexType>
08.</s:element>
09.<s:element name="HelloWorldResponse">
10.<s:complexType>
11.<s:sequence>
12.<s:element minOccurs="0" maxOccurs="1" name="HelloWorldResult" type="s:string"/>
13.</s:sequence>
14.</s:complexType>
15.</s:element>

//接受客户端POST过来的XML数据
$request = $HTTP_RAW_POST_DATA;

  这一段就字符串的

//执行调用客户端的XML请求后获取执行结果
$xmlrpc_response = xmlrpc_server_call_method($xmlrpc_server, $request, null);

  那返回数组的就比较麻烦了,我和老农搞了一两周才发现是WSDL文件写错了,看下面的一段

//把函数处理后的结果XML进行输出
header('Content-Type: text/xml');
echo $xmlrpc_response;

 

//销毁XML-RPC服务器端资源
xmlrpc_server_destroy($xmlrpc_server);
?>

01.<s:element name="GetMember">
02.<s:complexType>
03.<s:sequence>
04.<s:element minOccurs="1" maxOccurs="1" name="uid" type="s:int"/>
05.<s:element minOccurs="0" maxOccurs="1" name="uname" type="s:string"/>
06.</s:sequence>
07.</s:complexType>
08.</s:element>
09.<s:element name="GetMemberResponse">
10.<s:complexType>
11.<s:sequence>
12.<s:element minOccurs="0" maxOccurs="1" name="GetMemberResult" type="tns:ArrayOfMember"/>
13.</s:sequence>
14.</s:complexType>
15.</s:element>
16.<s:complexType name="ArrayOfMember">
17.<s:sequence>
18.<s:element minOccurs="0" maxOccurs="unbounded" name="Member" nillable="true" type="tns:Member"/>
19.</s:sequence>
20.</s:complexType>
21.<s:complexType name="Member">
22.<s:sequence>
23.<s:element minOccurs="1" maxOccurs="1" name="UserId" type="s:int"/>
24.<s:element minOccurs="0" maxOccurs="1" name="Name" type="s:string"/>
25.</s:sequence>
26.</s:complexType>

  服务器端构造好了,那么再构造我们的RPC客户端。客户端大致通过Socket访问XML-RPC服务器端的80端口,然后把需要调用的RPC接口封装到XML里,通过POST请求提交给RPC服务器端,最后获取服务器端返回结果。

  第一段GetMember是输入,最重要的是GetMemberResponse这段,看type=”tns:ArrayOfMember”这里,返回一 个数组,WSDL中定义了ArrayOf这个,后面的就简单了,ArrayOfMember的类型是type=”tns:Member” ,从name=”Member”得到要返回的数组,完工。

本文由宝马娱乐在线城发布于互联网络,转载请注明出处:PHP教程:WebService最常用的两种方法

关键词: