php soap 实例

简介: php soap编码转换在给CHINAZ资讯(dedecms)做同步bbsmax passport登陆api时,因为bbsmax使用utf-8编码,而资讯这边用的是GBK编码,导致乱码。开始想自己转码,但有点麻烦。

php soap编码转换
在给CHINAZ资讯(dedecms)做同步bbsmax passport登陆api时,因为bbsmax使用utf-8编码,而资讯这边用的是GBK编码,导致乱码。开始想自己转码,但有点麻烦。后面想SOAP既然用来针对不同平台,那肯定也包括编码问题,就又认真看了PHP手册,介绍里虽然没有提到,却发现Examples里有,访问很简单。
client=newSoapClient("some.wsdl",array(encoding=>GBK));PHPSoapHeaderphpsoapclientheaderserverheadersoapheaderheaderwebservicesoapw3saopheadersoapclientsoapserversoapFaultclient.php<?phpcli = new SoapClient(null, array('uri' => 'http://127.0.0.1/namespace/', 'location' => 'http://localhost/server.php', 'trace' => true));
h=newSoapHeader(http://127.0.0.1/namespace/,auth,123456789,false,SOAPACTORNEXT);cli->__setSoapHeaders(array(h));tryecho$cli>say();catch(Exceptione) {
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的角色(不是太理解)
注意看红色的一行,构造了一个soapHeader,header的名称为"auth",data为"123456789",mustUnderstand为false,actor为SOAP_ACTOR_NEXT。
注意观察server.php中的server类有一个方法"auth",刚好与header的名称对应,方法auth的参数u,就是soapHeader的data,soapServer接收到这个请求会,先调用auth方法,并把"123456789"作为参数传递给该方法。 mustUnderstand参数为false时,即便没有auth这个方法,say方法也会被调用,但是如果它为true的话,如果auth方法不存在,就会返回一个Soapfault告知该header没有被处理。 actor参数指名那些role必须处理该header,这儿我理解得不是太透彻,不好说。 大概就这样,关键点在于SoapHeader的构造。 soap官方:http://www.w3.org/TR/soap12-part1/ [转]使用SoapHeader实现Soap请求验证 在PHP的Soap 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  <?phpsoap_header = new SoapHeader("http://www.laruence.com", 'Authorise'
, new SoapUserInfo('laruence', 'password'), false, SOAP_ACTOR_NEXT);
?>
也许细心的同学会注意到第4个参数FALSE和第5个参数SOAP_ACTOR_NEXT, 这是什么呢? 我最后再讲.
然后, 创建客户端, 绑定SoapHeader
<?php
client=newSoapClient(wsdl);
client->__setSoapHeaders(array(soap_header));
client->__soapCall('request', array()); ?> 现在, 客户端已经发起了请求, 请求中也包含了SoapHeader, 其中有了我们验证需要的用户名/密码信息.  那么, 在服务端, 该如何做呢?  <?phpserver = 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/privateauthorized = 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的构造函数中, 我们可以指明一个Server的Actor, 比如:  <?phpserver = new SoapServer(wsdl,array(actor=>laruence));?>,ClientSoapHeader,actorlaruence,Server.phpSOAPWebphpphpsoap1server.php<?phpsoap = new SoapServer(null,array('uri'=>"http://10.10.10.24/"));//输入本台服务器的ip地址
soap>addFunction(say);//soap->addFunction(SOAP_FUNCTIONS_ALL); //不要忘了这个
soap>handle();//functionsay(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 (SoapFaultfault){
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();classMyclassfunctionsay($someword)return$someword;?>xyzworld<?try$client=newSoapClient(null,array(location=>"http://www.xiao688.com/server.php",uri=>"http://www.xiao688.com/"));vardump($client);echo$client>say("xyzworld");catch(SoapFaultfault){
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=newSoapServer(wsdl,array);wsdl为shoap使用得wsdl文件,wsdl是描述Web Service的一种 标准格式,若将wsdlnull使wsdlarray是 SoapServer的属性信息,是一个数组。

SoapServer对象的addFunction方法是用来声明哪个函数可以被客户端调用, 语法格式如下:
soap>addFunction(function_name);
其中,soapSoapServerfunction_name是需要被调用的函数名。

SoapServer对象的handle方法用来处理用户输入并调用相应的函数,最后返回 给客户端处理的结果。语法格式如下:
soap>handle([soap_request]);
其中,soapSoapServer,soap_request是一个可选参数,用来表示 用户的请求信息。如果不指定soaprequest2SoapClietSoapClientSoapServerSoapClient:soap = new SoapClient(wsdl,array);
其中,参数wsdlarray与SoapServer相同。 创建SoapClient对象后,调用服务端页面中的函数相当于调用了SoapClient的方法, 创建语法如下:
soap>userfunction(params);
其中,soapSoapClientuserfunctionparams 是要传入函数的参数。

3、SoapFault
SoapFault用于生成soap访问过程中可能出现的错误。创建一个soapFault对象的语法格式
如下:
fault=newSoapFault(faultcode,faultstring);faultcode是用户定义的错误代码,faultstringsoapFaultSoapFaultSoap访SoapFalutSoapFaultfault->faultcode;//错误代码
fault>faultstring;//fault是在前面创建的SoapFault对象。
目前的PHP AJAX 库很多,如:SAJAX、JPSPAN、xajax 、AJASON、flxAJAX、AjaxAC等
server端的代码: server.php

<?php
//声明一个函数add() ,并返回它的值
function add(a,b){
return a+b;
}
//实例化一个SoapServer对象, 并将add函数注册成为其方法
server=newSoapServer(null,array(uri=>http://localhost/));//serverURI()server->addFunction("add"); server>handle();?>使clientserver:client::clientclient.php<?php//访soaparrOptions=array( 'uri'=>'http://localhost/','location'=>'http://localhost/soap/server.php',
//注意: 这个location指定的是server端代码在服务器中的具体位置, 我的是在本地根目录下的soap目录中
,'trace'=>true, );
soapObject=newSoapClient(null,arrOptions); //实例化客户端对象 echo soapObject>add(20,30);//add50?>php5+webservice(phpsoapwebservice)SOAP访  SOAPSimpleObjectAccessProtocol  访SOAPXMLWEBSOAP使HTTPSMTPMIMERPC  SOAP  SOAP,  SOAP  SOAPRPC  SOAP使SOAP  SOAP/SOAP使XMLSOAPSOAPSOAPSOAPXML  SOAPHTTPSOAPHTTPHTTPSOAPSOAPHTTPHTTPSOAPHTTP使HTTPRPCHTTPRPCHTTPRPC使SOAPHTTP  SOAPTCPUDPWSDL  WebServicesDescriptionLanguageWebWebXMLphp5+webservice1,php.iniextension=phpsoap.dll(soap)soap.wsdlcacheenabled=1soap.wsdlcacheenabled=02,soap(ZendStudioForEclipse)2.1,(DizzyLion.php)ClassDizzyLion/@paramfloat$pa@paramfloat$pb@returnfloat/Publicfunctionsum($pa,$pb)Return$pa+$pb;wsdl2.2,wsdldizzylion.wsdlzendstudioZendStudioforEclipse6.1File>Export>PHP>WSDLFile"GenerateWSDLFile"ConfigurationnameFilenamewsdldizzylion.wsdlExportedfiles"Add"DizzyLion.phpclasserurlDizzyLion.php,DizzyLion.urlserver.phpWEB访URLhttp://localhot/server.php"finish"wsdl2.3,Soap(server.php)<?phpRequire./DizzyLion.php;server = new SoapServer('./dizzylion.wsdl');
server>setClass(DizzyLion);server->handle();
?>
3, 写Soap客户端。(client.php)
<?php
soap=newSoapClient(./dizzylion.wsdl);//dizzylion.wsdlURLechosoap->sum(1.1, 3.1);
?>

=======================================================

<?php
/**
 *    SoapClientAuth for accessing Web Services protected by HTTP authentication
 *    Author: tc
 *    Last Modified: 04/08/2011
 *    Update: 14/03/2012 - Fixed issue with CURLAUTH_ANY not authenticating to NTLM servers
 *    Download from: http://tcsoftware.net/blog/
 *
 *    Copyright (C) 2011  tc software (http://tcsoftware.net)
 *
 *    This program is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


    /**
     * SoapClientAuth
     * The interface and operation of this class is identical to the PHP SoapClient class (http://php.net/manual/en/class.soapclient.php)
     * except this class will perform HTTP authentication for both SOAP messages and while downloading WSDL over HTTP and HTTPS.
     * Provide the options login and password in the options array of the constructor.
     * 
     * @author tc
     * @copyright Copyright (C) 2011 tc software
     * @license http://opensource.org/licenses/gpl-license.php GNU Public License
     * @link http://php.net/manual/en/class.soapclient.php
     * @link http://tcsoftware.net/
     */
    class SoapClientAuth extends SoapClient{
	public $Username = NULL;
	public $Password = NULL;
	
	/**
	 * 
	 * @param string $wsdl
	 * @param array $options 
	 */
	function SoapClientAuth($wsdl, $options = NULL)
	{
	    stream_wrapper_unregister('https');
	    stream_wrapper_unregister('http');
	    stream_wrapper_register('https', 'streamWrapperHttpAuth');
	    stream_wrapper_register('http', 'streamWrapperHttpAuth');
	    
	    if($options)
	    {
		$this->Username = $options['login'];
		streamWrapperHttpAuth::$Username = $this->Username;
		$this->Password = $options['password'];
		streamWrapperHttpAuth::$Password = $this->Password;
	    }
	    
	    parent::SoapClient($wsdl, ($options?$options:array()));
	    
	    stream_wrapper_restore('https');
	    stream_wrapper_restore('http');
	}
	
	function __doRequest($request, $location, $action, $version) {

		$headers = array(
			'User-Agent: PHP-SOAP',
			'Content-Type: text/xml; charset=utf-8',
			'SOAPAction: "' . $action . '"',
			'Content-Length: ' . strlen($request),
			'Expect: 100-continue',
			'Connection: Keep-Alive'
		);
		
		$this->__last_request_headers = $headers;
		$ch = curl_init($location);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		
		curl_setopt($ch, CURLOPT_POST, TRUE);
		curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
		
		curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
		curl_setopt($ch, CURLOPT_FAILONERROR, FALSE);
		curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
		
		curl_setopt($ch, CURLOPT_USERPWD, $this->Username . ':' . $this->Password);
		curl_setopt($ch, CURLOPT_SSLVERSION, 3);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
		
		curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
		curl_setopt($ch, CURLOPT_VERBOSE, TRUE);
		curl_setopt($ch, CURLOPT_CERTINFO, TRUE);
		
		$response = curl_exec($ch);
		
		if(($info = curl_getinfo($ch)) && $info['http_code']==200)
		    return $response;
		else if($info['http_code']==401)
		    throw new Exception ('Access Denied', 401);	
		else if(curl_errno($ch)!=0)
		{
			throw new Exception(curl_error($ch), curl_errno($ch));
		}else
		    throw new Exception('Error', $info['http_code']);
	}
    }

    class streamWrapperHttpAuth
    {
	public static $Username = NULL;
	public static $Password = NULL;
	
	private $path = NULL;
	private $position = 0;
	private $buffer = NULL;
	private $curlHandle = NULL;
	
	public function stream_close()
	{
	    if($this->curlHandle)
		curl_close ($this->curlHandle);
	}
	
	public function stream_open($path, $mode, $options, &$opened_path)
	{
	    $this->path = $path;
	    $response = $this->postRequest($this->path);
	    $this->buffer = ($response!==FALSE?$response:NULL);
	    $this->position = 0;
	    return $response!==FALSE;
	}
	
	public function stream_eof()
	{
	    return $this->position>strlen($this->buffer);
	}
	
	public function stream_flush()
	{
	    $this->position = 0;
	    $this->buffer = NULL;
	}
	
	public function stream_read($count)
	{
	    if($this->buffer)
	    {
		$data = substr($this->buffer, $this->position, $count);
		$this->position += $count;
		return $data;
	    }
	    return FALSE;
	}
	
	public function stream_write($data)
	{
	    return ($this->buffer?TRUE:FALSE);
	}
	
	public function stream_seek($offset, $whence = SEEK_SET)
	{
	    switch($whence)
	    {
		case SEEK_SET:
		    $this->position = $offset;
		    break;
		case SEEK_CUR:
		    $this->position += $offset;
		    break;
		case SEEK_END:
		    $this->position = strlen($this->buffer) + $offset;
		    break;
	    }
	    
	    return TRUE;
	}
	
	public function stream_tell()
	{
	    return $this->position;
	}
	
	public function stream_stat()
	{
	    return array('size' => strlen($this->buffer));
	}
	
	public function url_stat($path, $flags)
	{
	    $response = $this->postRequest($path);
	    return array('size' => strlen($response));
	}
	
	protected function postRequest($path, $authType = CURLAUTH_ANY)
	{
	    $this->curlHandle = curl_init($path);
	    curl_setopt($this->curlHandle, CURLOPT_RETURNTRANSFER, TRUE);
	    curl_setopt($this->curlHandle, CURLOPT_FOLLOWLOCATION, TRUE);
	    if(streamWrapperHttpAuth::$Username)
	    {
		curl_setopt($this->curlHandle, CURLOPT_HTTPAUTH, $authType);
		curl_setopt($this->curlHandle, CURLOPT_USERPWD, streamWrapperHttpAuth::$Username . ':' . streamWrapperHttpAuth::$Password);
	    }
	    
	    curl_setopt($this->curlHandle, CURLOPT_SSLVERSION, 3);
	    curl_setopt($this->curlHandle, CURLOPT_SSL_VERIFYPEER, FALSE);
	    curl_setopt($this->curlHandle, CURLOPT_SSL_VERIFYHOST, 2);
	    
	    $response = curl_exec($this->curlHandle);
	    
	    if(($info = curl_getinfo($this->curlHandle)) && $info['http_code']==200)
	    {
		if(curl_errno($this->curlHandle)==0)
		{
		    return $response;
		}else
		    throw new Exception(curl_error($this->curlHandle), curl_errno($this->curlHandle));
	    }else if($info['http_code']==401)
	    { // Attempt NTLM Auth only, CURLAUTH_ANY does not work with NTML
		if($authType!=CURLAUTH_NTLM)
		    return $this->postRequest($path, CURLAUTH_NTLM);
		else
		{
		    throw new Exception ('Access Denied', 401);
		}
	    }else if(curl_errno($this->curlHandle)!=0)
	    {
		    throw new Exception(curl_error($this->curlHandle), curl_errno($this->curlHandle));
	    }else
		throw new Exception('Error', $info['http_code']);

	    return FALSE;
	}
    }
?>

  

 

zchd
+关注
目录
打赏
0
0
0
0
4
分享
相关文章
PHP中的设计模式:提高代码的可维护性与扩展性本文旨在探讨PHP中常见的设计模式及其应用,帮助开发者编写出更加灵活、可维护和易于扩展的代码。通过深入浅出的解释和实例演示,我们将了解如何使用设计模式解决实际开发中的问题,并提升代码质量。
在软件开发过程中,设计模式是一套经过验证的解决方案模板,用于处理常见的软件设计问题。PHP作为流行的服务器端脚本语言,也有其特定的设计模式应用。本文将重点介绍几种PHP中常用的设计模式,包括单例模式、工厂模式和策略模式,并通过实际代码示例展示它们的具体用法。同时,我们还将讨论如何在实际项目中合理选择和应用这些设计模式,以提升代码的可维护性和扩展性。
117 4
|
4月前
|
PHP
PHP的pcntl多进程用法实例
PHP使用PCNTL系列的函数也能做到多进程处理一个事务。
49 12
PHP与SOAP Web服务开发:基础与进阶教程
本文介绍了PHP与SOAP Web服务的基础和进阶知识,涵盖SOAP的基本概念、PHP中的SoapServer和SoapClient类的使用方法,以及服务端和客户端的开发示例。此外,还探讨了安全性、性能优化等高级主题,帮助开发者掌握更高效的Web服务开发技巧。
PHP中的设计模式:单例模式的深入探索与实践在PHP开发领域,设计模式是解决常见问题的高效方案集合。它们不是具体的代码,而是一种编码和设计经验的总结。单例模式作为设计模式中的一种,确保了一个类仅有一个实例,并提供一个全局访问点。本文将深入探讨单例模式的基本概念、实现方式及其在PHP中的应用。
单例模式在PHP中的应用广泛,尤其在处理数据库连接、日志记录等场景时,能显著提高资源利用率和执行效率。本文从单例模式的定义出发,详细解释了其在PHP中的不同实现方法,并探讨了使用单例模式的优势与注意事项。通过对示例代码的分析,读者将能够理解如何在PHP项目中有效应用单例模式。
PHP中的设计模式:如何提高代码的可维护性与扩展性在软件开发领域,PHP 是一种广泛使用的服务器端脚本语言。随着项目规模的扩大和复杂性的增加,保持代码的可维护性和可扩展性变得越来越重要。本文将探讨 PHP 中的设计模式,并通过实例展示如何应用这些模式来提高代码质量。
设计模式是经过验证的解决软件设计问题的方法。它们不是具体的代码,而是一种编码和设计经验的总结。在PHP开发中,合理地使用设计模式可以显著提高代码的可维护性、复用性和扩展性。本文将介绍几种常见的设计模式,包括单例模式、工厂模式和观察者模式,并通过具体的例子展示如何在PHP项目中应用这些模式。
PHP中的设计模式:单例模式的深入探索与实践在PHP的编程实践中,设计模式是解决常见软件设计问题的最佳实践。单例模式作为设计模式中的一种,确保一个类只有一个实例,并提供全局访问点,广泛应用于配置管理、日志记录和测试框架等场景。本文将深入探讨单例模式的原理、实现方式及其在PHP中的应用,帮助开发者更好地理解和运用这一设计模式。
在PHP开发中,单例模式通过确保类仅有一个实例并提供一个全局访问点,有效管理和访问共享资源。本文详细介绍了单例模式的概念、PHP实现方式及应用场景,并通过具体代码示例展示如何在PHP中实现单例模式以及如何在实际项目中正确使用它来优化代码结构和性能。
80 2
|
10月前
|
[网络安全/CTF] BUUCTF极客大挑战2019PHP解题详析(Dirsearch使用实例+php反序列化)
[网络安全/CTF] BUUCTF极客大挑战2019PHP解题详析(Dirsearch使用实例+php反序列化)
232 0
[CTF/网络安全]攻防世界unserialize3解题详析及php序列化反序列化实例讲解
序列化是指将数据结构或对象转换为可传输或可存储的格式的过程。这通常需要将数据转换为字节流或其他形式的编码格式,以便能够在不同的系统和应用程序之间进行传输或存储。
425 0
php结合redis实现高并发下的抢购、秒杀功能的实例
php结合redis实现高并发下的抢购、秒杀功能的实例
283 0

热门文章

最新文章