当前位置:文档之家› WebService最常用的两种方法

WebService最常用的两种方法

来自:https://www.doczj.com/doc/c73922101.html,/s/2009-07-14/1529984002.shtml
===========================================================================
【IT168 技术】企业级应用,主要是讲PHP5对Webservice的一些实现(以下的程序可以被Java,NET,C等正常调用)

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

客户端

代码:

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' => 'https://www.doczj.com/doc/c73922101.html,/SoapDiscovery/' ) );
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');
23.$out = $client->HelloWorld($parameters);
24.$datadb = $out->HelloWorldResponse;
25.var_dump($out);
26.?>
服务端

代码:

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' => 'https://www.doczj.com/doc/c73922101.html,/','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.?>
到这里应该都看的懂吧

下面是WSDL文件

代码:

001.
002.
003.
004.
005.
006.
007.
008.
009.
010.

011.

012.

013.
014.
015.
016.
017.

018.

019.

020.
021.
022.
023.
024.
025.

026.

027.

028.
029.
030.
031.
032.

033.

034.

035.
036.
037.
038.

039.

040.
041.
042.
043.
044.

045.

046.

047.

048.
049.
050.

051.
052.
053.

054.
055.
056.

057.
058.
059.

060.
061.
062.
063.
064.

065.
066.
067.
068.

069.

070.
071.
072.

ration name="HelloWorld">
073.
074.
075.
076.

077.
078.
079.

080.
081.
082.
083.
084.
085.

086.
087.
088.

089.

090.
091.
092.
093.
094.
095.
096.
097.

098.
099.
100.

101.

102.
103.
104.
105.
106.

107.
108.
109.

110.

111.

112.
113.
114.
115.

116.
117.
118.

119.

120.




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

01.
02.
03.
04.
05.
06.

07.

08.

09.
10.
11.
12.
13.

14.

15.



这一段就字符串的

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

01.
02.
03.
04.
05.
06.

07.

08.

09.
10.
11.
12.
13.

14.

15.


16.
17.
18.
19.

20.

21.
22.
23.
24.
25.

26.



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

Ping Service,博客程序提供一种通知机制,以便在第一时间将博客的更新信息发布到提供Ping Service服务的网站,写聚合的时候研究了一下

先看标准吧

这是一个标准的Ping Service,用XMLRPC来传数据的,注释写的这么详细,代码说明就不需要了吧,PHP5开启XMLRPC方法

client.php

代码:

01.
02.$host = 'zxsv';
03.$port = 80;
04.$rpc_server = '/test/xmlrpc_server.php';
05.$title = 'zxsv';
06.$server = 'http://zxsv/test/';
07.$rss = 'http://zxsv/test/rss.php';
08.//WeblogUpdates.Ping方法
09.$Ping = xmlrpc_encode_request('weblogUpdates.Ping', array($title, $server ));
10.//weblogUpdates.extendedPing方法
11.$extendedPing = xmlrpc_encode_request('weblogUpdates.extendedPing', array($title, $server, $rss ));
12.//调用rpc_client_call函数把所有请求发送给XML-RPC服务器端后获取信息
13.$response = rpc_client_call($host, $port, $rpc_server, $Ping);
14.$split = '';
15.$xml = explode($split, $response);
16.$xml = $split . array_pop($xml);
17.$response = xmlrpc_decode($xml);
18.//输出从RPC服务器端获取的信息
19.print_r($response);
20./**
21.* 函数:提供给客户端进行连接XML-RPC服务器端的函数
22.* 参数:
23.* $host 需要连接的主机
24.* $port 连接主机的端口
25.* $rpc_server XML-RPC服务器端文件
26.* $request 封装的XML请求信息
27.* 返回:连接成功成功返回由服务器端返回的XML信息,失败返回false
28.*/
29.function rpc_client_call($host, $port, $rpc_server, $request) {
30.
$fp = fsockopen($host, $port);
31.
$query = "POST $rpc_server HTTP/1.0\nUser_Agent: XML-RPC Client\nHost: ".$host."\nContent-Type: text/xml\nContent-Length: ".strlen($request)."\n\n".$request."\n";
32.
if (!fputs($fp, $query, strlen($query))) {
33.
$errstr = "Write error";
34.
return false;
35.
}
36.
$contents =

'';
37.
while (!feof($fp)){
38.
$contents .= fgets($fp);
39.
}
40.
fclose($fp);
41.
return $contents;
42.}
43.?>
server.php

代码:

01.
02./**
03.* 函数:提供给RPC客户端调用的函数
04.* 参数:
05.* $method 客户端需要调用的函数
06.* $params 客户端需要调用的函数的参数数组
07.* 返回:返回指定调用结果
08.*/
09.function rpc_server_extendedping($method, $params) {
10.
$title = $params[0];
11.
$server = $params[1];
12.
$rss = $params[2];
13.
//中间的判断,成功返回$XML_RPC_String
14.
$XML_RPC_String = array('flerror'=>false,'message'=>'Thanks for the ping.');
15.
return $XML_RPC_String;
16.}
17.function rpc_server_ping($method, $params) {
18.
$title = $params[0];
19.
$server = $params[1];
20.
//中间的判断,成功返回$XML_RPC_String
21.
$XML_RPC_String = array('flerror'=>false,'message'=>'Thanks for the ping.');
22.
return $XML_RPC_String;
23.}
24.//产生一个XML-RPC的服务器端
25.$xmlrpc_server = xmlrpc_server_create();
26.//注册一个服务器端调用的方法rpc_server,实际指向的是rpc_server_extendedping函数
27.xmlrpc_server_reGISter_method($xmlrpc_server, "weblogUpdates.extendedPing", "rpc_server_extendedping");
28.xmlrpc_server_register_method($xmlrpc_server, "weblogUpdates.Ping", "rpc_server_ping");
29.//接受客户端POST过来的XML数据
30.$request = $HTTP_RAW_POST_DATA;
31.//print_r($request);
32.//执行调用客户端的XML请求后获取执行结果
33.$xmlrpc_response = xmlrpc_server_call_method($xmlrpc_server, $request, null);
34.//把函数处理后的结果XML进行输出
35.header('Content-Type: text/xml');
36.echo $xmlrpc_response;
37.//销毁XML-RPC服务器端资源
38.xmlrpc_server_destroy($xmlrpc_server);
39.?>
类写的,有BUG

代码:

 01.
02.class Pings {
03.
public $xmlrpc_server;
04.
public $xmlrpc_response;
05.
public $methodName;
06.
public function __construct() {
07.
//产生一个XML-RPC的服务器端
08.
$this->xmlrpc_server = xmlrpc_server_create ();
09.
$this->run ();
10.
}
11.
12.
//注册一个服务器端调用的方法rpc_server,实际指向的是ping函数
13.
public function rpc_server() {
14.
$this->methodName = !$this->methodName ? 'weblogUpdates.extendedPing':'weblogUpdates.Ping';
15.
xmlrpc_server

_register_method ( $this->xmlrpc_server, $this->methodName, array (__CLASS__, "ping"));
16.
}
17.
/**
18.
* 函数:提供给RPC客户端调用的函数
19.
* 参数:
20.
* $method 客户端需要调用的函数
21.
* $params 客户端需要调用的函数的参数数组
22.
* 返回:返回指定调用结果
23.
*/
24.
public function ping($method, $params) {
25.
$this->title = $params [0];
26.
$this->server = $params [1];
27.
$this->rss = $params [2];
28.
$this->tag = $params [3];
29.
//$a = $this->title ? $this->update():'';
30.
$string = array ('flerror' => false, 'message' => 'Thanks for the ping.', 'legal' => "You agree that use of the https://www.doczj.com/doc/c73922101.html, ping service is governed by the Terms of Use found at https://www.doczj.com/doc/c73922101.html,." );
31.
return $string;
32.
}
33.
34.
public function update(){
35.
echo '这里放更新的一些条件';
36.
}
37.
38.
public function run() {
39.
$this->rpc_server ();
40.
$request = isset ( $GLOBALS ["HTTP_RAW_POST_DATA"] ) ? file_get_contents ( "php://input" ) : $GLOBALS ["HTTP_RAW_POST_DATA"];
41.
$this->xmlrpc_response = xmlrpc_server_call_method ( $this->xmlrpc_server, $request, null );
42.
//把函数处理后的结果XML进行输出
43.
header ( 'Content-Type: text/xml' );
44.
echo $this->xmlrpc_response;
45.
}
46.
47.
//销毁XML-RPC服务器端资源
48.
public function __destruct() {
49.
xmlrpc_server_destroy ( $this->xmlrpc_server );
50.
}
51.}
52.$Obj = new Pings ( );
53.?>
WebService的最常用的两种方法算是写齐了。

===========================================================================
来自:https://www.doczj.com/doc/c73922101.html,/phpzxh/archive/2011/04/21/2023431.html

PHP 使用soap有两种方式。

一、用wsdl文件

服务器端。

class service
{
public function HelloWorld()
{
return "Hello";
}
public function Add($a,$b)
{
return $a+$b;
}
}
$server=new SoapServer('soap.wsdl',array('soap_version' => SOAP_1_2));
$server->setClass("service");
$server->handle();
?>资源描述文件,可以用工具(zend studio)生成。其实就是一个xml文件。



argetNamespace="http://localhost/interface/">











































transport="https://www.doczj.com/doc/c73922101.html,/soap/http" />



namespace="http://localhost/interface/" />


namespace="http://localhost/interface/" />








客户端调用$soap = new SoapClient('http://localhost/interface/soap.wsdl');
echo $soap->Add(1,2);
?>二、不用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/interface/soap.php",
"uri" => "abcd", //资源描述符服务器和客户端必须对应
"style" => SOAP_RPC,
"use" => SOAP_ENCODED
));

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


}
?>

===========================================================================
来自:https://www.doczj.com/doc/c73922101.html,/brucehawking/blog/item/85ead08bbc16551cc9fc7a75.html


PHP SOAP 基础知识
一.基础知识

1.wsdl(web服务标记语言)
WSDL(网络服务描述语言,Web Services Description Language)是一门基于 XML 的语言,用于描述 Web Services 以及如何对它们进行访问。
具体参考请访问下面网址 https://www.doczj.com/doc/c73922101.html,/wsdl/index.asp

2.soap
SOAP 是一种简单的基于 XML 的协议,它使应用程序通过 HTTP 来交换信息。
具体参考请访问下面网址 https://www.doczj.com/doc/c73922101.html,/soap/index.asp

3.php扩展
具体参考请访问下面网址 https://www.doczj.com/doc/c73922101.html,/manual/en/book.soap.php

二.php soap开发模式

1. working in swdl mode(契约先行(Contract first)模式)
契约先行模式使用了一个用XML定义的服务接口的WSDL文件。WSDL文件定义了服务必须实现或客户端必须使用的接口。SoapServer和SoapClient的WSDL模式就基于这个概念。也就是用soap通讯的时候必须先有一个定义过的服务接口,才能进行通讯。
2. working in non-swdl mode(代码先行(Code first)模式)
在代码先行模式中,首先要先写出实现服务的代码。然后在大多数情况下,代码会产生一个契约,换种说法,一个WSDL。接着客户端在使用服务的时候就可以使用那个WSDL来获得服务的接口。尽管如此,PHP5的扩展并没有从代码输出一个WSDL的规定,考虑到这种情况,可以在non-WSDL模式下使用 SoapServer和SoapClient。也就是说在soap通讯的时候并不需要一个预先定义过的服务接口,代码会自动的产生。

三.参考例子:
下面介绍如何使用WSDL模式和non-WSDL模式来实现服务和客户端。相对而言,使用WSDL模式来实现服务和客户端会比较容易。

1. noWSDL模式实现

服务端 server.php
class test
{
function show()
{
return 'hello world!';
}
}
$server = new SoapServer(null, array('uri' => "http://test-uri/"));
$server->setClass('test');
$server->handle();
?>

客户端 client.php
$soap=new SoapClient(null, array(
'location' =>'http://soapserver_url/server.php',
'uri' => "http://test-uri/"));
print_r($soap->__getFunctions());
echo $soap->show();
?>

2. WSDL模式实现

第一步:编写服务端类文件

class.php
class test
{
function show()
{
return 'hello world!';
}
}
?>

第二步:将类文件生成 wsdl文件server.wsdl。
由于wsdl文件编写比较复杂,所以我们用第三方工具生成。我们以zend studio为例子演示:
Tools ==> WSDL Generator ==> Configration name : test; WSDL file name: server
==>NEXT==> 点击 + ==> 选择上面的创建的class.php ==> 这时候会看到一个 classes?? : URL Location的映射,保留 test类前面的勾,并将其url 设置为 SOAP Server的url:http://soapser

ver_url/server.php ==>点击Finish,ZDE就会创建一个非常漂亮的WSDL了?? 工作基本上完成了.

第三步:服务端编写:
require ' class..php '; //引入类文件
$server = new SoapServer('server.wsdl');
$server->setClass('test');
$server->handle();
?>

第四步:客户端编写
$soap = new SoapClient('http:// soapserver_url/server.wsdl');
print_r($soap->__getFunctions());
echo $soap->show();

以上两个例子只是一个简单的soap服务编写,已经可以满足大部分需要。如果需要更加高级的功能请参考其他方面的资料。

三.出现的问题。

1.在方法中对属性的赋值在其他方法中不起作用。
比如在客户端调用服务端某个方法对某个属性赋值。
在其他方法里就不能用。但在 __construct 方法中对属性的赋值是可以个在其他方法中使用的。

2. 提示 Client] looks like we got no XML document错误。
服务器端文件在 标签前后都不要有任何数据包括空格,空行。

3. Warning: SoapClient::SoapClient(): I/O warning : failed to load external entity
原因如下:PHP程序作为 SOAP客户端 采用 WSDL 模式访问远端服务器的时候,PHP是通过调用 libcurl 实现的。至少在 PHP5.2.X 是这样的。如果采用 non-WSDL 模式,就不需要 libcurl。在solaris 没有缺省安装 libcurl,也许是我没有安装。除了 了ibcurl以外,至少还关联的库包括:libidn,ibgcc,libiconv,libintl,openssl

===========================================================================
来自:https://www.doczj.com/doc/c73922101.html,/topic/152042

相关主题
文本预览
相关文档 最新文档