soap

$client = new SoapClient("some.wsdl", array('encoding'=>'GBK')); 
只要這麼簡單,剩下的PHP自己幫忙實現了!
通過SoapHeader實現身份認證
之前一直抱怨php的soap很傻,在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的角色(不是太理解)
注意看紅色的一行,構造了一個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 
<?php
$soap_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 = 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的構造函數中, 我們可以指明一個Server的Actor, 比如: 
<?php
$server = new SoapServer($wsdl, array('actor' => 'laruence'));
?>
這樣, 我們就可以在Client的SoapHeader中, 通過設置actor是laruence, 來讓指定的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); 
其中,$wsdl爲shoap使用得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,則表示服務器將接收用戶的全部 請求。 

2、SoapCliet 
SoapClient用於調用遠程服務器上的SoapServer頁面,並實現了對相應函數的調用 。創建一個SoapClient對象的語法格式如下: 
$soap = new SoapClient($wsdl,$array); 
其中,參數$wsdl和$array與SoapServer相同。 創建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 庫很多,如:SAJAX、JPSPAN、xajax 、AJASON、flxAJAX、AjaxAC等
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:簡單對象訪問協議
  (SOAP:Simple 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也可以綁定到TCP和UDP協議上。 
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.php的WEB訪問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.wsdl的URL了。
echo $soap->sum(1.1, 3.1);
?>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章