欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

php学习之道:php中soap的使用实例以及生成WSDL文件,提供自动生成WSDL文件的类库??SoapDiscovery.class.php类

程序员文章站 2022-05-23 15:16:47
...
1. web service普及: Webservice soap wsdl区别之个人见解

Web Service实现业务诉求: Web Service是真正“办事”的那个,提供一种办事接口的统称。
WSDL提供“能办的事的文档说明”: 对要提供的服务的一种描述格式。我想帮你的忙,但是我要告诉你我都能干什么,以及干这些事情需要的参数类型。
SOAP提供“请求”的规范: 向服务接口传递请求的格式,包括方法和参数等。你想让人家办事,总得告诉人家你想干什么吧,SOAP就是定义这个“请求”的格式的,按照SOAP定义的“请求”格式“书写”请求就可以保证Web Service能够正确的解读你想让它干什么以及你为它提供了什么参数。在这个请求中,你需要描述的主要问题有:向哪个Web Service发送请求,请求的参数类型、参数值、返回值类型。这些都“填写”完毕,也就完成了符合SOAP规范的SOAP消息。

wsdl和soap虽然是web service的两大标准,但是两者并没有必然的联系,都可以独立使用。
wsdl提供了一个统一的接口,目前已经成为一个国际上公认的标准,通过wsdl提供的接口可以访问不同类型的资源(如java、c#、C、C、C++等),因为wsdl是基于xml,与语言平台无关的。另外wsdl提供了binding和service元素,用以绑定接口到具体的服务,实现了接口与实现的分离。

soap(简单对象访问协议)是一种基于http的传输协议,用来访问远程服务

wsdl与soap的关系在于:wsdl绑定服务的时候可以设定使用的协议,协议可以是soap、http、smtp、ftp等任何一种传输协议,除此以外wsdl还可以绑定jms、ejb及local java等等,不过都是需要对binding和service元素做扩展的,而且需要扩展服务器的功能以支持这种扩展

soap协议是一种请求和应答协议规范,而http是web传输协议,soap的传输是可以基于http的,但也可以基于其他的传输协议,如ftp、smtp等。

简单对象访问协议(SOAP)是W3C组织的一个Note, 它描述了一种在分散的或分布式的环境中如何交换信息的轻量级协议。SOAP是一个基于XML的协议,它包括三个部分:SOAP封装(Envelop),封装定义了一个描述消息中的内容是什么,是谁发送的,谁应当接受并处理它以及如何处理它们的框架;SOAP编码规则(Encoding Rules),用于表示应用程序需要使用的数据类型的实例;SOAP RPC表示(RPC Representation),表示远程过程调用和应答的协定;SOAP可以和多种传输协议绑定(Binding),使用底层协议交换信息。在这个文档中,目前只定义了SOAP如何和HTTP以及HTTP扩展进行绑定的框架。

SOAP是个通信协议, SOAP在HTTP协议的基础上,把编写成XML的REQUEST参数, 放在HTTP BODY上提交个WEB SERVICE服务器(SERVLET,ASP什么的) 处理完成后,结果也写成XML作为RESPONSE送回用户端, 为了使用户端和WEB SERVICE可以相互对应,可以使用WSDL作为这种通信方式的描述文件,利用WSDL工具可以自动生成WS和用户端的框架文件,SOAP具备把复杂对象序列化捆绑到XML里去的能力。

SOAP的前身是RPC, 就是远程呼叫处理的协议,这个协议安全性不是很好,多数防火墙都会阻挡RPC的通信包,而SOAP则使用HTTP协议作为基本的协议,使用端口80使得SOAP可以透过防火墙,完成RPC的功能。

SOAP协议和HTTP协议一样,都是底层的通信协议,只是请求包的格式不同而已,SOAP包是XML格式的,现在我们编写WEB SERVICE不需要深入理解SOAP也没关系。如果SERVICE和CLIENT在同样的环境下使用SOAP,由于一般情况下都有自动生成SOAP程序框架的工具,因此不知道细节也没关系. 可是, 如果CLIENT和SERVICE的环境不同,比如说JAVA的Client和.NET的SERVICE进行通信,或者是VB CLIENT和TOMCAT下的JAVA SERVICE通信,还是要知道一点细节为好. 特别是, WSDL或者UDDI都不是标准,如果不让用就只好手工配制SOAP MESSAGE啦。

2. 使用类 "SoapDiscovery.class.php" 生成wsdl文档!

SOAP类型的接口
无关编程语言、无关平台、扩展性很好

要实现一个SOAP 型的接口,有两种方式:一种有WSDL文件方式、一中无WSDL文件方式!
对于热爱研究型的人来说,使用第一种方式可以让你清楚的了解PHP是怎么创建了一个Web Service!但第一种对于新手来说,创建一个XML格式的WSDL文件,是比较难的,这你的先了解熟悉什么是XML!学会XML语法!但对于一个急于解决问题的人来说!没有这么多的时间去熟悉!所以这是件烦恼的事!不过不急,上面说了,还有一种无需WSDL文件的方式!而且,本讲解还提供了一个自动生成WSDL文件的类!

讲解前,先配置下PHP的soap环境支持:
找到php.ini文件
;extension=php_soap.dll
删除掉";" ,重启apache服务器

一、有WSDL文件方式
在这里先介绍标准的webservice。 那么如何创建wsdl呢?对于PHP来说这确实是件很不容易的事情,有人说用zend studio创建很方便,这是一种方法。但对于那些不喜欢用zend studio的人来说,会觉得创建一个web service还要安装zend studio,太强人所难了。
在这里介绍一个简单的方法,到网上下载SoapDiscovery.class.php类(我本地有下载的),里面有个公用方法:getWSDL(),这个方法末尾是用的return语句,那么,你修改一下这个方法:
//return sprintf('%s%s%s%s%s%s', $headerWSDL, $portTypeWSDL, $bindingWSDL, $serviceWSDL, $messageWSDL, '');
//生成wsdl文件,将上面的return注释去掉,那么
$fso = fopen($this->class_name . ".wsdl" , "w");
fwrite($fso, sprintf('%s%s%s%s%s%s', $headerWSDL, $portTypeWSDL, $bindingWSDL, $serviceWSDL, $messageWSDL, ''));
现在生成wsdl的类有了,SoapDiscovery.class.php(源码在最末尾)。
再准备一个提供服务的Service.php类文件或者函数就可以创建wsdl了!
class Service {

public function HelloWorld() {
return "Hello";
}

public function Add($a, $b) {
return $a + $b;
}

}
?>

 下面创建wsdl文件的creat_wsdl.php
include("Service.php");
include("SoapDiscovery.class.php");

$disc = new SoapDiscovery('Service', 'soap'); //第一个参数是类名(生成的wsdl文件就是以它来命名的,例如:下面的Service.wsdl),即Service类,第二个参数是服务的名字(这个可以随便写)
$disc->getWSDL();
##说明:通过查看"SoapDiscovery.class.php"文件的源码发现,此成员函数如果开启return语句,会返回一个xml格式的字符串,如果用 $strXML = $disc->getWSDL();echo $strXML;那么在浏览器中将不能显示xml的wsdl文件。因为浏览器默认用的是"html/text"来返回stdout的内容,需要在php脚本的头部用:
header("Content-type: text/html; charset=utf-8"); 才可以让浏览器不把输出作为html而是作为xml来解析!
  用web访问的方式运行create_wsdl.php文件,此时会生成一个Service.wsdl的文件,下面将会用到这个文件!
注意:上面方法生成的wsdl文件在windows下面没问题,但是在Linux下面的wsdl文件中的"location=XXX" 段,确实没有服务器IP地址。所以要修改该代码中的: $_SERVER['SERVER_NAME'] 为 $_SERVER['SERVER_HOST'] ,因为在linux(nginx)下面,前者变量为空,这样才能生成正确的wsdl文档!


  再在Service.php文件中添加一些代码
class Service {

public function HelloWorld() {
return "Hello";
}

public function Add($a, $b) {
return $a + $b;
}

}

$server = new SoapServer('Service.wsdl', array('soap_version' => SOAP_1_2)); ##此处的Service.wsdl文件是上面生成的
$server->setClass("Service"); //注册Service类的所有方法
$server->handle(); //处理请求
?>

  创建webservice客户端程序,测试webservice是否有效,文件名是:client.php
将以下内容拷贝进去:
 ini_set('soap.wsdl_cache_enabled', "0"); //关闭wsdl缓存
$soap = new SoapClient('http://localhost/Dragon/soap/Service.php?wsdl');
 echo $soap->Add(28, 2);
echo $soap->__soapCall('Add',array(28,2))//或这样调用
#echo $soap->__Call('Add',array(28,2));

?>
  OK!测试通过!

  

二、无WSDL文件方式
  服务器端
class Service
{
public function HelloWorld()
{
return "Hello";
}
public function Add($a,$b)
{
return $a+$b;
}
}
$server=new SoapServer(null,array('uri' => "abcd"));
$server->setClass("Service");
$server->handle();
?>
   客户端
try {
$soap = new SoapClient(null, array(
"location" => "http://localhost/Dragon/soap/Service.php",
"uri" => "abcd", //资源描述符服务器和客户端必须对应
"style" => SOAP_RPC,
"use" => SOAP_ENCODED
));

echo $soap->Add(12, 2);
} catch (Exction $e) {
echo print_r($e->getMessage(), true);
}
?>