www.2527.com_澳门新葡8455手机版_新京葡娱乐场网址_
做最好的网站

PHP使用SOAP扩大完毕WebService的法门,无标题文章

2019-07-13 08:28 来源:未知

本文实例讲述了PHP使用SOAP扩展实现WebService的方法。分享给大家供大家参考,具体如下:

 

NuSOAP 发布Webservice

最近在一个PHP项目中对接外部接口涉及到WebService,搜索引擎上相关文章不是很多,找到的大都是引用一个号称很强大的开源软件NuSOAP(下载地址:),即一些类。文章写描述的环境是PHP 4.3,现在都流行PHP 5.2或PHP 5.3了。先拿来试试,运行出错,原来NuSOAP提供的soapclient类与PHP 5中新增了内置的SOAP扩展的SoapClient类冲突了。

 

PHP SOAP 服务器

  1. 用PHP和NuSoap来建立SOAP服务器非常容易。基本上,你只要写出你想要暴露给你的Web services的函数,然后用NuSoap去注册它们就可以了。OK,另外还需要两步才能完成PHP SOAP服务器的建立。首先你还要在你的PHP代码中创建NuSoap对象的一个实例,然后用HTTP POST方法将原始数据传给NuSoap进行处理
  2. NuSOAP的使用比较简单,其中最常用到的类是soap_serversoapclient, **其中soap_server用于创建 Webservice服务,类soapclient则用于调用Webservice **.这两个类的定义都在lib/nusoap.php中,因此我们在创建 或调用Webservice接口程序时均需要引用该文件.
  3. NuSoap是PHP环境下的WebService编程工具,用于创建或调用WebService。它是一个开源软件,是完全采用PHP语言编写的、通过HTTP收发SOAP消息的一系列PHP类,由NuSphere Corporation(http://dietrich.ganx4.com/nusoap/ )开发。NuSOAP的一个优势是不需要扩展库的支持,这种特性使得NuSoap可以用于所有的PHP环境,不受服务器安全设置的影响。

虽然NuSOAP号称可以用于所有的PHP 环境,不受服务器安全设置的影响。但需要引用一大堆类文件,还是觉得用PHP 5中新增了内置的SOAP扩展好一些,能实现实用就好。先了解一下SOAP:

利用NuSoap开发WebService(PHP)

分类: php 2010-09-08 12:00 5005人阅读 评论(1) 收藏 举报

webservicephpsoapstringencodingparsing

NuSoap是PHP环境下的WebService编程工具,用于创建或调用WebService,是一个开源软件。它完全采用PHP语言编写、通过HTTP收发SOAP消息的一系列PHP类,由NuSphere Corporation()开发。
它的优势是不需要扩展库的支持,这种特性使它可用于所有的PHP环境,不受服务器安全设置的影响。
1.首先,去http://sourceforge.net/projects/nusoap/下载nusoap-0.9.5.zip,解压后把lib文件夹放到与你的WebService程序相同的目录,如/WebService/lib。

2.
服务端:建立nusoapService.php文件。
<?php
    require_once("lib/nusoap.php");
    $server = new soap_server;
    //避免乱码
    $server->soap_defencoding = 'UTF-8';
    $server->decode_utf8 = false;
    $server->xml_encoding = 'UTF-8';
    $server->configureWSDL('sayHello');//打开wsdl支持
    /*
       注册需要被客户端访问的程序
       类型对应值:bool->"xsd:boolean"   string->"xsd:string" 
                int->"xsd:int"    float->"xsd:float"
    */
    $server->register( 'sayHello',    //方法名
    array("name"=>"xsd:string"),    //参数,默认为"xsd:string"
    array("return"=>"xsd:string") );//返回值,默认为"xsd:string"
    //isset 检测变量是否设置
    $HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
    //service 处理客户端输入的数据
    $server->service($HTTP_RAW_POST_DATA);
    /**
     * 供调用的方法
     * @param $name
     */
    function sayHello($name) {
       return "Hello, {$name}!";
    }
?>
注:
      1.文件代码不能有任何输出,否则调用时会报类似如下错误:
             XML error parsing SOAP payload on line x(行号): Reserved XML Name
      2.要以UTF-8 无BOM格式保存,不然客户端调用会出错。

3.
客户端:建立nusoapClient.php文件。
<?php
    require_once("lib/nusoap.php");
    /*
       通过WSDL调用WebService
       参数1 WSDL文件的地址(问号后的wsdl不能为大写)
       参数2 指定是否使用WSDL 
       $client = new soapclient(');
       */
    $client = new soapclient('');
    $client->soap_defencoding = 'UTF-8';
    $client->decode_utf8 = false;
    $client->xml_encoding = 'UTF-8';
    //参数转为数组形式传递
www.2527.com,    $paras=array('name'=>'Bruce Lee');
    //目标方法没有参数时,可省略后面的参数
    $result=$client->call('sayHello',$paras);
    //检查错误,获取返回值
    if (!$err=$client->getError()) { echo "返回结果:",$result;  }
    else { echo "调用出错:",$err; }
?>
注:用nusoap实现WebService,不要开启php的SOAP扩展

 

实验

  1. 首先,去 http://sourceforge.net/projects/nusoap/ 下载 nusoap.zip 。
  2. 服务端:建立 nusoapService.php 文件。
<?php
require_once ("./lib/nusoap.php");
$server = new nusoap_server ();
// 避免乱码
$server->soap_defencoding = 'UTF-8';
$server->decode_utf8 = false;
$server->xml_encoding = 'UTF-8';
$server->configureWSDL ('sayHello'); // 打开 wsdl 支持
/*
注册需要被客户端访问的程序
类型对应值:
    bool->"xsd:boolean"   
    string->"xsd:string"
    int->"xsd:int"    
    float->"xsd:float"
*/
$server->register ( 'sayHello', // 方法名
    array ("name" => "xsd:string" ), // 参数,默认为 "xsd:string"
    array ("return" => "xsd:string" ) // 返回值,默认为 "xsd:string"
    ); 

//isset  检测变量是否设置
$HTTP_RAW_POST_DATA = isset ( $HTTP_RAW_POST_DATA ) ? $HTTP_RAW_POST_DATA : '';
//service  处理客户端输入的数据
$server->service ( $HTTP_RAW_POST_DATA );

/**
 * 供调用的方法
 * @param $name
 */
function sayHello($name) {
    return "Hello,  { $name } !";
}
?>
  1. 客户端:建立nusoapClient.php
<?php
require_once ("./lib/nusoap.php");
/*
通过 WSDL 调用 WebService
参数 1 WSDL 文件的地址 (问号后的wsdl不能为大写)
参数 2  指定是否使用 WSDL
$client = new nusoap_client('http://localhost/nusoapService.php?wsdl',true);
*/
$client = new nusoap_client ( 'http://localhost/nusoapService.php' );
$client->soap_defencoding = 'UTF-8';
$client->decode_utf8 = false;
$client->xml_encoding = 'UTF-8';
// 参数转为数组形式传递
$paras = array ('name' => 'Bruce Lee' );
// 目标方法没有参数时,可省略后面的参数
$result = $client->call ( 'sayHello', $paras );
// 检查错误,获取返回值
if (! $err = $client->getError ()) {
    echo " 返回结果: ", $result;
} else {
    echo " 调用出错: ", $err;
}
?>

<?php
require_once ("./lib/nusoap.php");
/*
通过 WSDL 调用 WebService
参数 1 WSDL 文件的地址 ( 问号后的 wsdl 不能为大写 )
参数 2  指定是否使用 WSDL
$client = new nusoap_client('http://localhost/nusoapService.php?wsdl',true);
*/
$client = new nusoap_client ( 'http://localhost/nusoapService.php?wsdl',true);
$client->soap_defencoding = 'UTF-8';
$client->decode_utf8 = false;
$client->xml_encoding = 'UTF-8';
// 参数转为数组形式传递
$paras = array ('name' => 'Bruce Lee' );
// 目标方法没有参数时,可省略后面的参数
$client->call ( 'sayHello', $paras );
$document = $client->document;
echo $document; 
?>

注:返回结果:Hello, { Bruce Lee } !

一、SOAP和XML-PRC比较

WSDL

  1. WSDL是一种用于描述Web Service的XML语言。它是一种机读格式,把所有的访问服务所必须的信息提供给Web Service客户端。NuSOAP专门提供一个类进行WDSL文件的解析,并且从中提取信息。soapclient对象使用wsdl类来减轻开发者调用服务的难度。通过WSDL信息的帮助来创建报文,程序员仅仅需要知道操作的名字和参数就能调用它。

  2. 通过NuSOAP使用WSDL提供以下几点优点:
    所有的服务元文件,如命名空间(namespaces),endpoint URLs,参数名(parameter names)等等都可以直接从WSDL文件获得,这样就允许客户端动态的适应服务器端的变化。因为从服务器随时可以获得,所以这些数据不再需要在用户脚本中使用硬性编码。
    它允许我们使用soap_proxy类。这个类派生自soapclient类,增加了WDSL文件中详细列出的操作所对应的方法。现在用户通过它可以直接调用这些方法。

  3. soapclient 类包含一个getProxy()方法,它返回一个soap_proxy类的一个对象。soap_proxy类派生自soapclient类,增加了对应于 WSDL文档中定义的操作的方法, 并且允许用户调用一个endpoint的远程方法。这仅仅适用于soapclient对象用WDSL文件初始化的情况。优点是易于用户使用,缺点是性能--PHP中创建对象是耗时的--且不为功利目的服务 (and this functionality serves no utilitarian purpose)

<?php
require_once ("./lib/nusoap.php");
$client = new nusoap_client ( 'http://localhost/nusoapService.php?wsdl',true);
$client->soap_defencoding = 'UTF-8';
$client->decode_utf8 = false;
$client->xml_encoding = 'UTF-8';
//生成proxy类  
$proxy = $client->getProxy();  
//调用远程函数  
$sq = $proxy->sayHello('Bruce Lee'); 
if (!$err=$proxy->getError()) {  
print_r($sq);  
} else {  
print "ERROR: $err";  
}  

?>  
  1. 运行server端文件页面:http://localhost/nusoapService .php生成的wsdl文件
    点击方法名称。这样我们通过在service中增加了几行代码我们就通过使用NuSOAP为service提供了一个可视化的文档。但是,这还不是所有我们能做的。
<definitions xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://192.168.119.224/soap/sayHello" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://192.168.119.224/soap/sayHello">
    <types>
        <xsd:schema targetNamespace="http://192.168.119.224/soap/sayHello">
            <xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
            <xsd:import namespace="http://schemas.xmlsoap.org/wsdl/"/>
        </xsd:schema>
    </types>
    <message name="sayHelloRequest">
        <part name="name" type="xsd:string"/>
    </message>
    <message name="sayHelloResponse">
        <part name="return" type="xsd:string"/>
    </message>
    <portType name="sayHelloPortType">
        <operation name="sayHello">
            <input message="tns:sayHelloRequest"/>
            <output message="tns:sayHelloResponse"/>
        </operation>
    </portType>
    <binding name="sayHelloBinding" type="tns:sayHelloPortType">
        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="sayHello">
            <soap:operation soapAction="http://192.168.119.224/nusoapService.php/sayHello" style="rpc"/>
            <input>
                <soap:body use="encoded" namespace="" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
            </input>
            <output>
                <soap:body use="encoded" namespace="" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
            </output>
        </operation>
    </binding>
    <service name="sayHello">
        <port name="sayHelloPort" binding="tns:sayHelloBinding">
            <soap:address location="http://192.168.119.224/nusoapService.php"/>
        </port>
    </service>
</definitions>

在Web服务发展的初期,XML格式化消息的第一个主要用途是,应用于XML-RPC协议,其中RPC代表远程过程调用。在XML远程过程调用(XML-RPC)中,客户端发送一条特定消息,该消息中必须包括名称、运行服务的程序以及输入参数。

错误解决

  1. NuSoap 调用WebService出现乱码解决方法:
$client->soap_defencoding = 'utf-8';  
$client->decode_utf8 = false;  
$client->xml_encoding = 'utf-8';  
  1. 文件代码不能有任何输出 , 否则调用时会报类似如下错误:
    XML error parsing SOAP payload on line x( 行号 ): Reserved XML Name
  2. 用 nusoap 实现 WebService, 不要开启 php 的 SOAP 扩展,原因是nusoap的SoapClient类和php5内置的SOAP类有冲突。
    解决方案
    1. 修改php.ini不加载php5内置的soap扩展(windows下是php_soap.dll)。
    2. 也有给nusoap的SoapClient类改名的。

身份认证

<?php
header('content-type: text/xml; charset=UTF-8');
require_once('nusoap.php');
$params = array('AuthenticationHeader' => array(
    'Content-Type' => 'text/xml; charset=UTF-8',
    'SOAPAction' => 'YourFunstion',
)
);
$client = new nusoap_client('http://www.yourdomain.com/service.asmx?wsdl', true, '', '', '', '');
$client->setHeaders('  
<tns:AuthenticationHeader xmlns:tns="http://tempuri.org/webservice">
  <tns:UserName>username</tns:UserName> 
  <tns:Password>password</tns:Password>   
 </tns:AuthenticationHeader>
');
$err = $client->getError();
if ($err) {
    echo '<h2>Constructor error</h2><pre>' . $err . '</pre>';
}
$result = $client->call('YourFunction', $params, '', '', false, true);
if ($client->fault) {
    echo '<h2>Fault</h2><pre>';
    print_r($result);
    echo '</pre>';
} else {
    $err = $client->getError();
    if ($err) {
        echo '<h2>Error</h2><pre>' . $err . '</pre>';
    } else {
        echo '<h2>Result</h2><pre>';
//print_r($result);
        echo '</pre>';
    }
}
echo '<h2>Request</h2><pre>' . htmlspecialchars($client->request, ENT_QUOTES) . '</pre>';
echo '<h2>Response</h2><pre>' . htmlspecialchars($client->response, ENT_QUOTES) . '</pre>';
?>

XML-RPC只能使用有限的数据类型种类和一些简单的数据结构。人们认为这个协议还不够强大,于是就出现了SOAP——其最初的定义是简单对象访问协议。之后,大家逐渐意识到SOAP其实并不简单,而且也不需要必须使用面向对象语言,所以,现在人们只是沿用SOAP这个名称而已。

XML-RPC只有简单的数据类型集,取而代之,SOAP是通过利用XML Schema的不断发展来定义数据类型的。同时,SOAP也能够利用XML 命名空间,这是XML-RPC所不需要的。如此一来,SOAP消息的开头部分就可以是任何类型的XML命名空间声明,其代价是在系统之间增加了更多的复杂性和不兼容性。

随着计算机行业的觉醒,人们发现了基于XML的Web服务的商业潜力,于是,各家公司开始不断地发掘想法、观点、论据以及标准化尝试。W3C曾经设法以“Web服务活动”的名义来组织成果展,其中也包括实际做出SOAP的XML协议工作组(XML Protocol Working Group)。与Web服务有关的标准化成果(从某种程度上说与SOAP相关或者依赖于SOAP)的数量已经倍增了到了令人惊讶的程度。

最初,SOAP是作为XML-RPC的扩展而发展起来的,它主要强调的是,通过从WSDL文件中所获得的方法和变量名来进行远程过程调用。现在,通过不断进步,人们发现了更多的使用SOAP的方式,而不仅仅是采用“文件”方式——基本上是使用一个SOAP信封来传送XML格式化文件。无论如何,要掌握SOAP,了解WSDL所扮演的角色是最根本的。

二、SOAP数据包结构解析

SOAP的消息被称为一个SOAP Envelope,包括SOAP Header和SOAP Body。其中,SOAP Header可以方便的插入各种其它消息来扩充Web Service的功能,比如Security(采用证书访问Web Service),SOAP Body则是具体的消息正文,也就是Marshall后的信息。

SOAP调用的时候,也就是向一个URL(比如 )发送HTTP Post报文(根据SOAP规范,HTTP Get报文也可被支持),调用方法的名字在HTTP Request Header SOAP-Action中给出,接下来就是SOAP Envelope了。服务端接到请求,执行计算,将返回结果Marshall成XML,用HTTP返回给客户端。

三、SOAP简单示例

SOAP开发一般有三种方式选择:

1)、PEAR自带的SOAP扩展;
2)、PHP自带的SOAP扩展;
3)、NuSOAP(纯PHP) 。

PHP 5中新增了内置的SOAP扩展,作为PHP的一部分提供的,因此不需要下载、安装和管理单独的包。这是第一个用C而不是PHP为PHP编写的SOAP实现,因此作者声称它的速度要快得多。相关文档包含在PHP手册的Function Reference部分(php_soap.dll)。

一个访问.NET WEB服务的客户端例子:

< ? php
$objSoapClient = new SoapClient("http://www.webservicemart.com/uszip.asmx?WSDL");
$param = array("ZipCode"=>'12209'); 
$out = $objSoapClient->ValidateZip($param);
$data = $out->ValidateZipResult;
echo $data;
?>

四、实例

1)、用PHP建立SOAP服务

建立soap_server.php(虚拟路径为:

< ? php
/**
* A simple math utility class
*/
class math{
  /**
  * Add two integers together
  *
  * @param integer $a The first integer of the addition
  * @param integer $b The second integer of the addition
  * @return integer The sum of the provided integers
  */
  public function add($a, $b){
    return $a   $b;
  }
  /**
  * Subtract two integers from each other
  *
  * @param integer $a The first integer of the subtraction
  * @param integer $b The second integer of the subtraction
  * @return integer The difference of the provided integers
  */
  public function sub($a, $b){
    return $a - $b;
  }
  /**
  * Div two integers from each other
  *
  * @param integer $a The first integer of the subtraction
  * @param integer $b The second integer of the subtraction
  * @return double The difference of the provided integers
  */
  public function div($a, $b){
    if($b == 0){
      throw new SoapFault(-1, "Cannot divide by zero!");
    }
    return $a / $b;
  }
}
$server = new SoapServer('math.wsdl', array('soap_version'=>SOAP_1_2));
$server->setClass("math");
$server->handle(); 
?>

注:

a)、math类是即将公开的webservice;
b)、$server->setClass,不是$server->addClass。
2)、用PHP客户端访问刚建立SOAP服务

< ? php
// $client = new SoapClient('http://localhost/php/soap/math.wsdl');
$client = new SoapClient("http://localhost/php/soap/soap_server.php?WSDL");
try{
  $result = $client->div(8, 2); // will cause a Soap Fault if divide by zero
  print "The answer is: $result";
}catch(SoapFault $e){
  print "Sorry an error was caught executing your request: {$e->getMessage()}";
}
?>

本质上,

可以用ZendStudio生成静态的WSDL文件,此时用到math类的phpdoc作为生成WSDL的元数据。用ZendStudio生成wsdl文件时,必须正确说明Web服务目标地址,片断如下:

...
  <service name="mathService">
    <port binding="typens:mathBinding" name="mathPort">
      <soap:address location="http://localhost/php/soap/soap_server.php"></soap:address>
    </port>
  </service>
...

注:调用PHP Webserver的方法必须传入命名参数。

更多关于PHP相关内容感兴趣的读者可查看本站专题:《PHP运算与运算符用法总结》、《PHP网络编程技巧总结》、《PHP基本语法入门教程》、《php操作office文档技巧总结(包括word,excel,access,ppt)》、《php日期与时间用法总结》、《php面向对象程序设计入门教程》、《php字符串(string)用法总结》、《php mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

希望本文所述对大家PHP程序设计有所帮助。

您可能感兴趣的文章:

  • php实现通过soap调用.Net的WebService asmx文件
  • PHP使用SOAP调用.net的WebService数据
  • THINKPHP3.2使用soap连接webservice的解决方法
TAG标签:
版权声明:本文由澳门新葡8455手机版发布于www.2527.com,转载请注明出处:PHP使用SOAP扩大完毕WebService的法门,无标题文章