php+soap

php+soap

php soap编码转换

在给CHINAZ资讯(dedecms)做同步bbsmax passport登陆api时,因为bbsmax使用utf-8编码,而资讯这边用的是GBK编码,导致乱码。开始想自己转码,但有点麻烦。后面想SOAP既然用来针对不同平台,那肯定也包括编码问题,就又认真看了PHP手册,介绍里虽然没有提到,却发现Examples里有,访问很简单。

  1. $client = new SoapClient("some.wsdl"array('encoding'=>'GBK'));  

只要这么简单,剩下的PHP自己帮忙实现了!

通过SoapHeader实现身份认证

之前一直抱怨phpsoap很傻,在client端有设置header的方法,在server端却没有取header的方法。那是很傻很天真,直接用正则表达式从soap信封的header中提取header信息。
最近由于有项目要发布webservice,重新燃起对soap的兴趣,看了w3的英文文档,那是个云里雾里。收集了一些资料,做了一个关于saop header进行身份认证的实验。
在这个实验中,假定soap client用一个字符串作为身份认证的标识,soap server取到这个字符串后,对其进行辨认,如果与期望相符合,认证通过,如果不符,抛出soapFault
理论就不多说了,我也不懂,直接上代码
client.php
<?php
$cli = new SoapClient(null, array('uri' => 'http://127.0.0.1/namespace/', 'location' => 'http://localhost/server.php', 'trace' => true));
$h = new SoapHeader('http://127.0.0.1/namespace/', 'auth', '123456789', false, SOAP_ACTOR_NEXT);
$cli->__setSoapHeaders(array($h));
try {
    echo $cli->say();
} catch (Exception $e) {
    echo $e->getMessage();
}

server.php
<?php
class Server{
   public function auth($a)
    {
        if($a != '123456789'){
            throw new SoapFault('Server', '
您无权访问');
        }
    }
    function say()
    {
        return 'Hi';
    }

$srv = new SoapServer(null, array('uri' => 'http://localhost/namespace'));
$srv->setClass('Server');
$srv->handle();

以上代码就实现了认证的功能,最关键的地方就是SoapHeader的构造。soapHeader有五个构造参数,

Namespace    无用

Name    鉴别身份标识的函数或者方法名

Data    存放标识身份的字符串

mustUnderstand    是否必须处理该header 

actor    处理该header的角色(不是太理解)

注意看红色的一行,构造了一个soapHeaderheader的名称为"auth"data"123456789"mustUnderstandfalseactorSOAP_ACTOR_NEXT
注意观察server.php中的server类有一个方法"auth",刚好与header的名称对应,方法auth的参数$u,就是soapHeaderdatasoapServer接收到这个请求会,先调用auth方法,并把"123456789"作为参数传递给该方法。
mustUnderstand
参数为false时,即便没有auth这个方法,say方法也会被调用,但是如果它为true的话,如果auth方法不存在,就会返回一个Soapfault告知该header没有被处理。
actor
参数指名那些role必须处理该header,这儿我理解得不是太透彻,不好说。
大概就这样,关键点在于SoapHeader的构造。
soap
官方:http://www.w3.org/TR/soap12-part1/

[]使用SoapHeader实现Soap请求验证

PHPSoap Extension对于SoapServer来说并没有方法可用得到/处理客户端发送的SoapHeader信息.
网上也有很多人认为只能通过读取POST过来的请求XML文件分析才能得到客户端发送过来的SoapHeader.其实在SoapServer其实是有一种办法可用把SoapHeader当作一个请求来处理从而获取到客户端提交的SoapHeader信息

假设客户端代码如下

 

<?php
/*
* 保存用户名和密码的载体
*/
class SoapUserInfo {
/**
* @var char $name
*/
 public $name;
/**
* @var char $password
*/
public $password;
public function __construct($l, $p) {
    $this->Password = $p;
    $this->Username = $l;
}
}
?>

然后客户端生成SoapHeader 

<?php
$soap_header = new SoapHeader("http://www.laruence.com", 'Authorise'
, new SoapUserInfo('laruence', 'password'), false, SOAP_ACTOR_NEXT);
?>

也许细心的同学会注意到4个参数FALSE5个参数SOAP_ACTOR_NEXT这是什么呢我最后再讲

然后创建客户端绑定SoapHeader 

<?php
$client = new SoapClient($wsdl);
$client->__setSoapHeaders(array($soap_header));
$client->__soapCall('request', array());
?>

现在客户端已经发起了请求请求中也包含了SoapHeader, 其中有了我们验证需要的用户名/密码信息

那么在服务端该如何做呢

<?php
$server = new SoapServer('laruence.wsdl');
$server->setClass('InterfaceClass');
$server->handle();
?>

关键的地方就在服务端接收请求以后会实例化一个处理类然后分析SoapHeader, 接着就会调用InterfaceClass::Authorise这个方法(Authorise是我们请求头中的变量名), 所以我们就可用在InterfaceClass类中定义个Authorise方法并在这个方法中对SoapHeader中的信息做验证

然后请求体(Soap body)中的方法被调用因为不论Authorise方法返回什么(除非exit), 请求体中的方法一定会被调用所以要寻找个变量记录验证的结果

<?php
class InterfaceClass {
/**
* @var bool $authorized
*/
private $authorized = FALSE;
/*
* Authentication function
*
* @param string username
* @param string password
*/
public function Authentication($username, $password) {
    $this->authorized = validateUser($username, $password);
}
/*
* Test method
*/
public function request(){
    if ($this->authorized) {
        //验证成功, 继续处理.
    } else {
        //验证失败, 拒绝请求.
    }
}
}
?>

当然对于网上说的另外一种方法通过分析请求的XML文件也可以

<?php
class InterfaceClass {
/**
* @var bool $authorized
*/
private $authorized = FALSE;
function __construct() {
    $xml = file_get_contents('php://input');
    //分析xml, 获得SoapHeader数据, 验证
}
}
?>
Must Understand 

这个参数指明了是否服务端必须要了解SoapHeader, 如果这个参数为真而服务端并不能识别响应的Header, 则会引发一个Soap Fault(Header not understood). 

SOAP_ACTOR_NEXT 

actor指明了SoapHeader要传递给谁被谁处理

SOAP_ACTOR_NEXT的意思就是下一个接受到这个请求头的Service, 在本文的例子中只有一个Server,当然也就没有关系了

SoapServer的构造函数中我们可以指明一个ServerActor, 比如

<?php
$server = new SoapServer($wsdl, array('actor' => 'laruence'));
?>

这样我们就可以在ClientSoapHeader通过设置actorlaruence, 来让指定的Server来获得我们设置的头部的信息

php SOAP实现Web 服务例子 php  先要开启php_soap模块

一。

方法1
服务器文件叫 server.php
<?php
$soap = new SoapServer(null,array('uri'=>"
http://10.10.10.24/"));//输入本台服务器的ip地址
$soap->addFunction('say');                                   //
添加输出函数
$soap->addFunction(SOAP_FUNCTIONS_ALL);   //
不要忘了这个
$soap->handle();                                                   //
注意
function say($sth){
   return $sth;

?> 

客户端 输出的是hello world
<?php
try {
   $client = new SoapClient(null,
       array('location' =>"
http://10.10.10.24/server.php",'uri'=> "http://10.10.10.24/")
   );
   echo $client->say("hello world");
} catch (SoapFault $fault){
   echo "Error: ",$fault->faultcode,", string: ",$fault->faultstring;
}
?> 

 二。

服务器端文件server.php
<?php
$classmap = array();
//
注意和实例一的不同
$soap = new SoapServer(null,array('uri'=>"http://10.10.10.24/", "classmap" => $classmap));
$soap->setClass('Myclass');
$soap->handle();
class Myclass {
   function say($someword){
      return $someword;
   }
}
?>
客户端 输出的是xyz world 

<?
try {
        $client = new SoapClient(null,
          array('location' =>"
http://www.xiao688.com/server.php",'uri'=> "http://www.xiao688.com/")
       );
   var_dump($client);
   echo $client->say("xyz world");
} catch (SoapFault $fault){
       echo "Error: ",$fault->faultcode,", string: ",$fault->faultstring;

 

php soap实例

php提供了一个专门用于soap操作的扩展库,使用该扩展库后 可以直接在php中进行soap操作。下面将介绍soap的基本操作。 
一、soap扩展的使用方法 
php
soap扩展库通过soap协议实现了客服端与服务器端的数据交互操作。从php5.0后,php就自带了soap的支持。使用 soap扩展库首先需要修改php安装目录下的配置文件php.ini 来激活soap扩展库。 php.ini文件中找到如下所示的一行代码,去掉前面的注释(;) ;extension=php_soap.dll 修改后,重启web服务器即可激活soap扩展。在soap扩展库中,主要 包括三种对象。 
1
SoapServer 
SoapServer
用于创建php服务器端页面时定义可被调用的函数及返回 响应数据。创建一个SoapServer对象的语法格式如下

 $soap = new SoapServer($wsdl,$array);  

其中,$wsdlshoap使用得wsdl文件,wsdl是描述Web Service的一种 标准格式,若将$wsdl设置为null,则表示不使用wsdl模式。$array SoapServer的属性信息,是一个数组。

   

SoapServer对象的addFunction方法是用来声明哪个函数可以被客户端调用, 语法格式如下:

$soap->addFunction($function_name);  

其中,$soap是一个SoapServer对象,$function_name是需要被调用的函数名。

 

 SoapServer对象的handle方法用来处理用户输入并调用相应的函数,最后返回 给客户端处理的结果。语法格式如下:  

$soap->handle([$soap_request]);  

其中,$soap是一个SoapServer对象,$soap_request是一个可选参数,用来表示 用户的请求信息。如果不指定$soap_request,则表示服务器将接收用户的全部 请求。  

 

2SoapCliet  

SoapClient用于调用远程服务器上的SoapServer页面,并实现了对相应函数的调用 。创建一个SoapClient对象的语法格式如下
$soap = new SoapClient($wsdl,$array);  

其中,参数$wsdl$arraySoapServer相同。 创建SoapClient对象后,调用服务端页面中的函数相当于调用了SoapClient的方法, 创建语法如下

$soap->user_function($params); 
其中,$soap是一个SoapClient对象,user_function是服务器端要调用的函数,$params 是要传入函数的参数。  


3
SoapFault 
SoapFault
用于生成soap访问过程中可能出现的错误。创建一个soapFault对象的语法格式

 如下: 
$fault = new SoapFault($faultcode,$faultstring); 
其中,$faultcode是用户定义的错误代码,$faultstring是用户自定义的错误信息。soapFault 对象会在服务器端页面出现错误时自动生成,或者通过用户自行创建SoapFault对象时生成。对于 Soap访问时出现的错误,客户端可通过捕捉SoapFalut对象来获得相应的错误信息。 在客户端捕获SoapFault对象后,可以通过下面的代码获得错误代码和错误信息。 
$fault->faultcode;//
错误代码  

$fault->faultstring;//错误信息 
其中,$fault是在前面创建的SoapFault对象。  

目前的PHP AJAX 库很多,:SAJAXJPSPANxajax AJASONflxAJAXAjaxAC
server
端的代码: server.php

<?php 

 //声明一个函数add() ,并返回它的值  

function add($a,$b){  

return $a+$b;  

//实例化一个SoapServer对象并将add函数注册成为其方法  

$server = new SoapServer(null,array('uri'=>'http://localhost/')); //指定server端代码的URI(资源标志符)  

$server->addFunction("add"); $server->handle(); ?>

然后使用client端的代码来调用server端的代码: client的代码也很简单如下:
这个是client端的代码client.php
<?php  

//建立一个参数数组,存储要访问的提供soap服务的计算机的地址与程序

$arrOptions=array( 'uri'=>'http://localhost/','location'=>'http://localhost/soap/server.php', 

//注意这个location指定的是server端代码在服务器中的具体位置我的是在本地根目录下的soap目录中

,'trace'=>true, );  

$soapObject = new SoapClient(null,$arrOptions); //实例化客户端对象 echo $soapObject->add(20,30); //调用服务器端的函数add并返回值50 

 ?>

 

php5+ webservice (php soap webservice) 

SOAP简单对象访问协议

  (SOAPSimple Object Access Protocol

  简单对象访问协议(SOAP)是一种轻量的、简单的、基于XML 的协议,它被设计成在WEB 上交换结构化的和固化的信息。SOAP 可以和现存的许多因特网协议和格式结合使用,包括超文本传输协议(HTTP),简单邮件传输协议(SMTP),多用途网际邮件扩充协议(MIME)。它还支持从消息系统到远程过程调用(RPC)等大量的应用程序。

  SOAP 包括四个部分:

  SOAP 封装:它定义了一个框架该框架描述了消息中的内容是什么,谁应当处理它以及它是可选的还是必须的。

  SOAP 编码规则:它定义了一种序列化的机制,用于交换应用程序所定义的数据类型的实例。

  SOAP RPC 表示:它定义了用于表示远程过程调用和应答的协定。

  SOAP 绑定:定义了一种使用底层传输协议来完成在节点间交换SOAP封装的约定。

  SOAP 消息基本上是从发送端到接收端的单向传输,但它们常常结合起来执行类似于请求应答的模式。所有的SOAP 消息都使用XML 编码。一条SOAP 消息就是一个包含有一个必需的SOAP 的封装包,一个可选的SOAP 标头和一个必需的SOAP 体块的XML 文档。

  把SOAP 绑定到HTTP 提供了同时利用SOAP 的样式和分散的灵活性的特点以及HTTP 的丰富的特征库的优点。在HTTP 上传送SOAP 并不是说SOAP 会覆盖现有的HTTP 语义,而是HTTP 上的SOAP 语义会自然的映射到HTTP 语义。在使用HTTP 作为协议绑定的场合中,RPC 请求映射到HTTP 请求上,而RPC 应答映射到HTTP 应答。然而,在RPC 上使用SOAP 并不仅限于HTTP 协议绑定。

  SOAP也可以绑定到TCPUDP协议上。  

WSDL 简介

  Web Services Description Language的缩写,是一个用来描述Web服务和说明如何与Web服务通信的XML 语言。  

php5+ webservice

1,首先要设置服务器环境。

  修改php.ini 

  得添加extension=php_soap.dll (加载soap 内置包

  修改soap.wsdl_cache_enabled=1  改为soap.wsdl_cache_enabled=0 

   

2,soap 服务端。(Zend Studio For Eclipse 编写

  2.1, 写一个用来提供给客户端用的类文件( DizzyLion.php ) 

  Class DizzyLion {

                      / **

                      * 求和函数

                      * @param float $p_a

                      * @param float $p_b

                      * @return float           

                      * /

                   Public function sum($p_a, $p_b){

                          Return $p_a + $p_b;

                   }

 }

说明:写上函数的标准注释有利于下面做wsdl的工作。

2.2, 生成wsdl 文件。(dizzylion.wsdl)如果这个你能手写,那你真是太强了。我用zend studio 生成的。

       我用的Zend Studio for Eclipse 6.1 

       'File'->'Export'->'PHP'->'WSDL File' 

       "Generate WSDL File" 的窗口中。

       Configuration name 取自己想设的名字;File name 指定要生成wsdl文件(dizzylion.wsdl);Exported files "Add"添加刚刚的DizzyLion.php类文件;在classer url 就会出现DizzyLion.php的所有类勾选DizzyLion. url 写入server.phpWEB访问URL如:http://localhot/server.php。点"finish"就好了。如果有上面的标准注释这里就不用再去设置wsdl里对应参数类型之类了。

2.3, Soap 服务端文件(server.php) 

       <?php

              Require './DizzyLion.php';

              $server = new SoapServer('./dizzylion.wsdl');

              $server->setClass('DizzyLion');

              $server->handle();

         ?>

3, Soap客户端。(client.php) 

<?php

   $soap = new SoapClient('./dizzylion.wsdl'); //如果是远程,那当然写dizzylion.wsdlURL了。

   echo $soap->sum(1.1,  3.1);

?>

  运行client.php 得到4.2 . 

 

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值