工作中需要用php调用web
service接口,对php不熟,上网搜搜,发现关于用php调用web
service的文章也不多,不少还是php4里用nusoap这个模块调用的方法,其实php5里已经包含了处理soap的模块,但是资料太少了,上php官网上查帮助,写的不是很容易理解,经过多次实践,终于搞清楚了,php调用web
service还是非常简单的。下面用一个例子说明:

extension=php_openssl.dll

extension=php_soap.dll

php.ini 这2项要开通

web service服务是一个用java写的简单服务,环境为Tomcat6.0 + Axis2,暴露的方法为  String hello(String name)

传递一个String参数name,然后返回给客户端。

使用php5开发客户端:

<?php

header("content-type:text/html;charset=utf-8");

try {

//$client = new SoapClient("HelloService.wsdl",array('encoding'=>'UTF-8'));

$client = new SoapClient("http://localhost:8080/axis2/services/HelloService?wsdl",array('encoding'=>'UTF-8'));

var_dump($client->__getFunctions());

print("<br/>");

var_dump($client->__getTypes());

print("<br/>");

$parm1 = "php client call";

$param = array('param0' => $parm1);

$arr = $client->hello($param);

print_r($arr);

} catch (SOAPFault $e) {

print $e;

}

?>

代码确实很简单吧,创建SoapClient对象时,可以使用保存在本地WSDL文件,也可以使用远程的地址,后面的array数组里可以带上很多的参数,具体参数可以查php的SoapClient帮助,这里带的是字符集编码,如果调用方法的参数里有中文,一定要指定字符集编码,否则会出错。

调用web service前可以先调用SoapClient的__geunctions()和__getTypes()方法看一下你要调用的web service暴露的方法,参数和数据类型,需要注意的是传入的参数名一定要和soapclient里面定义的一致,否则参数是传不过去的。(本人在这个上面延误了很长时间 c#调用不用指定参数名,真奇怪啊)

不知道WSDL的情况也可以调用WS,需要使用SoapClient的__soapCall()或__call()方法,具体使用方法可以查php的帮助文档。

另外发现个问题,如果web service方法返回的是xml格式的字符串,php接收到以后会自己把数据内容解析出来,而不是xml字符串.

有个叫Nusoap类,在php4下比较流行。但是淡水这次玩的是php5,所以他就没戏了。
先恶补一下相关知识。
先要打开php5的web service扩展。linux下,嗯,好像不会-_-!。windows下,把php.ini文件中 extension=php_soap.dll 去掉注释即可。
方法:
SoapClient->__soapCall()
说明:
class SoapClient {
mixed
__soapCall ( string function_name, array arguments [, array options [,
mixed input_headers [, array &output_headers]]])
}
In
WSDL mode, you can simply call SOAP functions as SoapClient methods.
This method useful in non-WSDL mode when soapaction is unknown, uri
differs from the default or when sending and/or receiving SOAP Headers
返回值:
一个简单类型的返回值,或是一个关联数组
例子:

<?php
 
$client = new SoapClient("some.wsdl");
$client->SomeFunction($a, $b, $c);
 
$client->__soapCall("SomeFunction",
                     array($a, $b, $c)
                     );
$client->__soapCall("SomeFunction", 
                    array($a, $b, $c), 
                    NULL,
                    new SoapHeader(), 
                    $output_headers
                    );
 
 
$client = new SoapClient(null, array('location' =>"http://localhost/soap.php",'uri'=> "http://test-uri/"));
$client->SomeFunction($a, $b, $c);
$client->__soapCall("SomeFunction", 
                    array($a, $b, $c)
                    );
$client->__soapCall("SomeFunction", 
                    array($a, $b, $c),
                    array('soapaction' => 'some_action','uri' => 'some_uri')
                    );
?>

1.in WSDL mode
soapCall应用web service,例子用的是asp.net的web service,提供service.asmx页面,调用及查看都比较简单,手册上的example也大多是这个类型,比较简单.

SOAP发送的协议:

POST /servicepath/service.asmx HTTP/1.1
Host: 211.186.1.4
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: “http://211.186.5.15/Service/ServiceMethod”

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <ServiceMethod xmlns="http://211.186.5.15/Service">
      <param1>string</param1>
      <param2>string</param2>
      <param3>string</param3>
    </ServiceMethod>
  </soap:Body>
</soap:Envelope>

调用方法:

<?php
$client = new SoapClient("http://www.xxx.com/service/service.asmx?WSDL");
//向SOAP服务方发送参数值
$param1 = "p1";
$param2 = "p2";
$param3 = "p3";
 
//serviceParam1,serviceParam2,serviceParam3为发送参数值所对应的参数名(或service端提供的字段名)
$param = array('serviceParam1' => $param1,'serviceParam2' =>$param2,'serviceParam3' => $param3);
 
//默认以parameters字段标示传递的参数数组(这里的web services是.net提供的,所以和php提供的Web service不同)
$arr = $client->__soapCall('ServiceMethod',array('parameters' => $param));
//这里淡水推荐直接使用web services提供的方法,如
//$arr = $client->ServiceMethod($param);
 
print_r($arr);
?>

2.in non-WSDL mode
这种情况下soapaction is unknown

SOAP发送协议:

POST /services/SoapMethod?WSDL HTTP/1.1
Host: 220.211.1.12:8088
Connection: Keep-Alive
User-Agent: PHP-SOAP/5.2.5
Content-Type: text/xml; charset=utf-8
SOAPAction: “urn:SoapMethod#ServiceMethod”
Content-Length: 1297

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"xmlns:ns1="urn:SoapMethod" 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:ns2="http://220.211.1.12"SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:ServiceMethod>
<ServiceMethodSection xsi:type="ns2:ServiceObjectType">
<param1 xsi:type="xsd:string">01019</param1>
<param2 xsi:type="xsd:long">10</param2>
<param3 xsi:type="xsd:long">0</param3>
<param4 xsi:type="xsd:long">11</param4>
</ServiceMethodSection>
</ns1:ServiceMethod>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

调用方法:

<?php
//传递一个参数
try {
      $client = new SoapClient(
                      null,
                      array('location' =>'http://192.168.1.180:8088/services/SoapPage?WSDL','uri' =>'http://192.168.1.180:8088/services/')
                      );    
      $result =  $client->__soapCall('ServiceMethod', array('fieldName' =>"data")); //以数组形式传递params 
      //$result =  $client->__soapCall('ServiceMethod', array(new SoapParam("data", 'fieldName')));  //以构造服务端参数的形式构造参数传递给服务端  
      var_dump($result);
  } 
  catch (Exception $e) 
  {
      printf("Message = %s",$e->__toString());
  }
?>

附注一下:
class SoapParam {
__construct ( mixed data, string name )
}
参数:
data
The
data to pass or return. You can pass this parameter directly as PHP
value, but in this case it will be named as paramN and the SOAP Service
may not understand it.

name
参数名

<?php
//传递多个参数:
//如果服务端在non wsdl的情况下要求传递一个对象参数,该对象中包含多个属性,则
 
try {
      $client = new SoapClient(
                      null, 
                      array('location' =>'http://192.168.1.180:8088/services/SoapPage?WSDL','uri' => 'urn:SoapName')
                      );//uri部分也可能是uri地址
 
      class Obj{ 
       public $param1 = '01019';
       public $param2 = 10;
       public $param3 = 0;
       public $param4 = 11;
      }
 
    $struct = new Obj();  //创建服务端要求传递的对象
    //如果服务端变态到传递的参数有的参数类型是你编程语言中没有的数据类型,
    //如php,没有Java的Long类型(一般web service考虑通用性,数据类型都是string或int型)
    //就要将参数进行强制类型转换
    //这样的处理也只是在SOAP传输中将xml的参数类型替换成服务端所要求的类型名
    //并不是真实转化传递的数据类型
    $struct->param1 = iconv('gb2312','utf-8',$struct->param1);
    $struct->param2 = new SoapVar($struct->param2,XSD_LONG);
    $struct->param3 = new SoapVar($struct->param3,XSD_LONG);
    $struct->param4 = new SoapVar($struct->param4,XSD_LONG);
 
    //序列化对象中使用SoapVar的方法参考php手册对SoapVar的解释,每个参数都解释的很清楚
    $soapstruct = new SoapVar($struct, SOAP_ENC_OBJECT, "ServiceObjectType","http://soapinterop.org/xsd"); //对象序列化,注意区分,SOAP对象的序列化不是用serialize
    
      $result =  $client-> ServiceMethod(new SoapParam($soapstruct,'ServiceMethodSection'));      //$result =  $client->__soapCall('ServiceMethod', array(new SoapParam($soapstruct, 'ServiceMethodSection')));           var_dump($result);  } catch (Exception $e) {      printf("Message = %s",$e->__toString());  }

?>

php5调用web service的更多相关文章

  1. php5调用web service (笔者测试成功)

    转自:http://www.cnblogs.com/smallmuda/archive/2010/10/12/1848700.html 感谢作者分享 工作中需要用php调用web service接口, ...

  2. ORACLE存储过程调用Web Service

    1. 概述 最近在ESB项目中,客户在各个系统之间的服务调用大多都是在oracle存储过程中进行的,本文就oracle存储过程调用web service来进行说明.其他主流数据库,比如mysql和sq ...

  3. C#开发和调用Web Service

    http://blog.csdn.net/h0322/article/details/4776819 1.1.Web Service基本概念 Web Service也叫XML Web Service ...

  4. 通过ksoap2-android来调用Web Service操作的实例

    import java.io.IOException; import org.ksoap2.SoapEnvelope;import org.ksoap2.serialization.SoapObjec ...

  5. 使用Android应用调用Web Service

    Java本身提供了丰富的Web  Service支持,比如Sun公司指定的JAX-WS  2规范,还有Apache开源组织所提供的Axis1.Axis2.CXF等,这些技术不仅可以用于非常方便地对外提 ...

  6. Dynamic CRM 2013学习笔记(二十五)JS调用web service 实现多条记录复制(克隆)功能

    前面介绍过如何克隆一条当前的记录: Dynamic CRM 2013学习笔记(十四)复制/克隆记录 , 主要是通过界面上加一个字段,单击form上的clone 按钮时,改变这个字段的值以触发插件来实现 ...

  7. ASP.NET调用Web Service

    1.1.Web Service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求, ...

  8. delphi调用web service出现 Unable to retrieve the URL endpoint for Service/Port .....

    delphi调用web service出现 Unable to retrieve the URL endpoint  for Service/Port, 错误截图如下 查了很长时间, 发现在DataM ...

  9. C#使用SOAP调用Web Service

    程序代码 using System;using System.IO;using System.Net;using System.Text; namespace ConsoleApplication1{ ...

随机推荐

  1. Android数据存储-通过SharedPreferences实现记住密码的操作

    在Android中登陆中,为了实现用户的方便,往往需要根据用户的需要进行记住密码的操作,所以,在Android数据存储中SharedPreferences恰恰可以实现这一点 下面,小编将带领大家通过S ...

  2. Android成长日记-ListView

    数据适配器:把复杂的数据(数组,链表,数据库,集合等)填充在指定的视图界面上 适配器的类型: ① ArrayAdapter(数组适配器):用于绑定格式单一的数据 数据源:可以是集合或数组 ① Simp ...

  3. Automated CMS category, version identification (CMS vulnerability detection)

    catalog . 引言 . 不同CMS版本标的文件路径调研 . Code Example 1. 引言 微软解决大量CVE补丁更新的检测时候,采取的思路不是根据MD5对单个漏洞文件(.dll..sys ...

  4. matlab从txt文本导入数据作图

    Matlab上 fr = fopen('d:\Matlab\长期纪录2014-3-11.txt', 'r');data=fscanf(fr,'%f',[1,inf]);axis([0 90000 -8 ...

  5. 数据结构算法C语言实现(二十七)--- 7.2图的遍历

    一.简述 栈与队列,DFS与BFS.仅以连接表为例实现. 二.头文件 BFS要用到的头文件 //3_4_part1.h /** author:zhaoyu email:zhaoyu1995.com@g ...

  6. Android中定时执行任务的3种实现方法

    在Android开发中,定时执行任务的3种实现方法: 一.采用Handler与线程的sleep(long)方法(不建议使用,java的实现方式)二.采用Handler的postDelayed(Runn ...

  7. POJ3659 [usaco2008jan_gold]电话网络

    校内OJ上的题,刚开始做的时候以为是道SB题10分钟就能搞完.. 然后准备敲了才发现自己是个SB.. 刚开始以为是个很裸的TreeDP,然后就只设了两个状态,但是怎么想怎么不对.复杂度好像要爆炸.改成 ...

  8. BZOJ4653: [Noi2016]区间

    传送门 UOJ上卡掉一个点,COGS上卡掉两个点..弃疗,不改了,反正BZOJ上过啦hhh 先把区间按长度递增排序.然后每次用线段树维护区间最大覆盖次数,用一个指针随便扫扫就行了. //NOI 201 ...

  9. STM8L --- External interrupt

    note 1:  Several interrupts can be pending at the same time. When an interrupt request is not servic ...

  10. mybatis的批量删除

    公司工程用的是Mybatis的example的类,自动生成了对数据库的操作,批量操作的今天用到了,两种方式,一种需要拓展它生成的类,另一种自带的. 批量删除的id是以集合List传递 id以List& ...