原文:
PHP函數(shù)參考32-一次清楚SOAP擴(kuò)展 - 9ong
PHP函數(shù)參考33-一次清楚RPC框架Yar - 9ong
安裝soap擴(kuò)展
## 下載
wget -O php7.1.26.tar.gz http://cn2.php.net/get/php-7.1.26.tar.gz/from/this/mirror
## 解壓
tar xvf php7.1.26.tar.gz
## 進(jìn)入擴(kuò)展目錄
cd php-7.1.26/
## 配置
./configure --enable-soap=shared
## 編譯so文件
make
## 復(fù)制so文件到PHP擴(kuò)展目錄中
sudo cp modules/soap.so /usr/lib/php/20160303/
如果configure過(guò)程中提示報(bào)錯(cuò):
error: xml2-config not found. Please check your libxml2 installation
sudo apt-get install libxml2-dev
什么是SOAP
SOAP 是簡(jiǎn)單對(duì)象訪問(wèn)協(xié)議的首字母縮寫。它是一種基于 XML 的消息傳遞協(xié)議,用于在計(jì)算機(jī)之間交換信息嬉橙。SOAP 是 XML 規(guī)范的一個(gè)應(yīng)用程序。SOAP 是一種旨在通過(guò) Internet 進(jìn)行通信的通信協(xié)議做院。
SOAP 可以擴(kuò)展 HTTP 以進(jìn)行 XML 消息傳遞。
SOAP 為 Web 服務(wù)提供數(shù)據(jù)傳輸濒持。
SOAP 可以交換完整的文檔或調(diào)用遠(yuǎn)程過(guò)程键耕。
SOAP 可用于廣播消息。
SOAP 與平臺(tái)和語(yǔ)言無(wú)關(guān)弥喉。
SOAP 是定義發(fā)送信息的方式為 XML 方式郁竟。
SOAP 使客戶端應(yīng)用程序能夠輕松連接到遠(yuǎn)程服務(wù)并調(diào)用遠(yuǎn)程方法。
SOAP 擴(kuò)展主要用來(lái)處理 RPC 形式的 Web Services由境。不過(guò)棚亩,你也可以使用文本形式的 WSDL 文件配合 WSDL 模式的服務(wù)端和客戶端。
關(guān)于更多介紹:SOAP Web 服務(wù)介紹 - SegmentFault 思否
php的SOAP擴(kuò)展
SoapClient 類
這個(gè)類用來(lái)使用 Web Services虏杰。SoapClient 類可以作為給定 Web Services 的客戶端讥蟆。
它有兩種操作形式:
- WSDL 模式
- Non-WSDL 模式
在 WSDL 模式中,構(gòu)造器可以使用 WSDL 文件名作為參數(shù)纺阔,并自動(dòng)從 WSDL 中提取使用服務(wù)時(shí)所需要的信息瘸彤。
Non-WSDL 模式中使用參數(shù)來(lái)設(shè)置使用服務(wù)時(shí)所需要的信息。這個(gè)類有許多可以用來(lái)使用服務(wù)的有用的方法笛钝。其中 SoapClient::__soapCall() 是最重要的质况。這個(gè)方法可以用來(lái)調(diào)用服務(wù)中的某個(gè)操作愕宋。
SoapServer 類
這個(gè)類可以用來(lái)提供 Web Services。與 SoapClient 類似结榄,SoapServer 也有兩種操作模式:WSDL 模式和 non-WSDL模式中贝。這兩種模式的意義跟 SoapClient 的兩種模式一樣。在 WSDL 模式中臼朗,服務(wù)實(shí)現(xiàn)了 WSDL 提供的接口邻寿;在 non-WSDL 模式中,參數(shù)被用來(lái)管理服務(wù)的行為视哑。
在 SoapServer 類的眾多方法中绣否,有三個(gè)方法比較重要。它們是 SoapServer::setClass()挡毅、SoapServer::addFunction() 和 SoapServer::handle()蒜撮。
SoapServer::setClass()方法設(shè)定用來(lái)實(shí)現(xiàn) Web Services 的類。SoapServer::setClass 所設(shè)定的類中的所有公共方法將成為 Web Services 的操作(operation)慷嗜。
SoapServer::addFunction() 方法用來(lái)添加一個(gè)或多個(gè)作為 Web Services 操作(operation)的函數(shù)淀弹。
SoapServer:: handle() 方法指示 Web Services 腳本開(kāi)始處理進(jìn)入的請(qǐng)求。Web Services 腳本是用 PHP 腳本寫的一個(gè)或多個(gè) SoapServer 對(duì)象的實(shí)例庆械。盡管你可以有不止一個(gè)的 SoapServer 對(duì)象,但通常的習(xí)慣是一個(gè)腳本只擁有一個(gè) SoapServer 實(shí)例菌赖。在調(diào)用 SoapServer::handle() 方法之前缭乘,Web Services 腳本會(huì)使用設(shè)置在 SoapServer 對(duì)象實(shí)例上的任何信息來(lái)處理進(jìn)入的請(qǐng)求和輸出相應(yīng)的內(nèi)容。
SoapFault 類
這個(gè)類從 Exception 類繼承而來(lái)琉用,可以用來(lái)處理錯(cuò)誤堕绩。SoapFault 實(shí)例可以拋出或獲取 Soap 錯(cuò)誤的相關(guān)信息并按程序員的要求處理。
SoapHeader 類
這個(gè)類可以用來(lái)描述 SOAP headers邑时。它只是一個(gè)只包含構(gòu)造器方法的數(shù)據(jù)容器奴紧。
SoapParam 類
SoapParam 也是一個(gè)只包含構(gòu)造器方法的數(shù)據(jù)容器。這個(gè)方法可以用來(lái)描述傳遞給 Web Services 操作的參數(shù)晶丘。在 non-WSDL 模式中這是一個(gè)很有用的類黍氮,可以用來(lái)傳遞所期望格式的參數(shù)信息。
SoapVar 類
SoapVar 也是一個(gè)只包含構(gòu)造器的低級(jí)類浅浮,與 SoapHeader 和 SoapParam 類相似沫浆。這個(gè)類可以用來(lái)給一個(gè)Web Services 操作傳遞編碼參數(shù)。這個(gè)類對(duì) non-WSDL 中傳遞類型信息是非常有用的滚秩。
注:SoapParam 和 SoapVar 主要用來(lái)封裝用于放入 SOAP 請(qǐng)求中的數(shù)據(jù)专执,他們主要在 non-WSDL 模式下使用。事實(shí)上郁油,在 WSDL 模式下本股,SOAP 請(qǐng)求的參數(shù)可以通過(guò)數(shù)組方式包裝攀痊,SOAP 擴(kuò)展會(huì)根據(jù) WSDL 文件將這個(gè)數(shù)組轉(zhuǎn)化成為 SOAP 請(qǐng)求中的數(shù)據(jù)部分,所以并不需要這兩個(gè)類拄显。而在 non-WSDL 模式下蚕苇,由于沒(méi)有提供 WSDL 文件,所以必須通過(guò)這兩個(gè)類進(jìn)行包裝凿叠。
SoapHeader 類用來(lái)構(gòu)造 SOAP 頭涩笤,SOAP 頭可以對(duì) SOAP 的能力進(jìn)行必要的擴(kuò)展。SOAP 頭的一個(gè)主要作用就是用于簡(jiǎn)單的身份認(rèn)證盒件。
WSDL VS. non-WSDL 模式
Web Services 有兩種實(shí)現(xiàn)模式:契約先行(Contract first)模式和代碼先行(Code first)模式蹬碧。
契約先行模式使用了一個(gè)用 XML 定義的服務(wù)接口的WSDL文件。WSDL 文件定義了服務(wù)必須實(shí)現(xiàn)或客戶端可以使用的接口炒刁。SoapServer 和 SoapClient 的 WSDL 模式就基于這個(gè)概念恩沽。
在代碼先行模式中,首先要先寫出實(shí)現(xiàn)服務(wù)的代碼翔始。然后在大多數(shù)情況下罗心,代碼會(huì)產(chǎn)生一個(gè)契約(可以借助一些工具生成),換種說(shuō)法城瞎,一個(gè) WSDL 文件渤闷。接著客戶端在使用服務(wù)的時(shí)候就可以使用那個(gè) WSDL 來(lái)獲得服務(wù)的接口及其他信息。盡管如此脖镀,PHP5 的擴(kuò)展并沒(méi)有從代碼輸出一個(gè) WSDL 的實(shí)現(xiàn)飒箭,考慮到這種情況,可以在 non-WSDL 模式下使用 SoapServer 和 SoapClient蜒灰。
范例
SOAP服務(wù)端
SOAPHandler.php
class SOAPHandler
{
/**
* 檢查$_SERVER中的PHP_AUTH_USER
*/
public function check(){
if ($_SERVER['PHP_AUTH_USER'] != 'jm' || $_SERVER['PHP_AUTH_PW'] != 'chinese') {
header('WWW-Authenticate: Basic realm="NMG Terry"');
header('HTTP/1.0 401 Unauthorized');
exit();
}
}
/**
* 檢查header中的Authorization: Basic am06Y2hpbmVzZQ==
* @param type $auth
* @throws SOAPFault
*/
public function auth($auth)
{
if ($auth->string[0] != 'jm' || $auth->string[1] != 'chinese') {
throw new SOAPFault('Server', 'No Permission From Server');
}
}
// 域名鏈接字符串
public function domainLink($domain = '',$url="")
{
return "<a href=".$url.">".$domain."</a>";
}
public function getServerInfo(){
return $_SERVER;//array
}
}
soapServer.php
require 'SOAPHandler.php';
$handler = new SOAPHandler();
$handler->check();
// no wsdl mode
try {
$serverUri = "soap/soapServer";
$config = array(
'uri' => $serverUri
);
$server = new SOAPServer(null, $config);
$server->setObject($handler);//設(shè)置處理請(qǐng)求的對(duì)象弦蹂,也可以使用setClass設(shè)置處理請(qǐng)求的類
$server->handle();//開(kāi)始處理請(qǐng)求
} catch (SOAPFault $f) {
echo "Error:".$f->getMessage();
}
SOAP客戶端
$serverLocation = "http://demo.130.com/FunctionsReference/soap/soapServer.php";
$serverUri = "soap/soapServer";
$config = [
'location' => $serverLocation,
'uri' => $serverUri,
'login' => 'jm',//[PHP_AUTH_USER] => jm | [PHP_AUTH_PW] => chinese | Authorization: Basic am06Y2hpbmVzZQ==
'password' => 'chinese',
'trace' => true
];
try{
$auth = ['jm', 'chinese'];
// no wsdl
$client = new SOAPClient(null, $config);
$header = new SOAPHeader("soap/header", 'auth', $auth, false,SOAP_ACTOR_NEXT);//SOAP_ACTOR_NEXT:soap服務(wù)端接收到請(qǐng)求并進(jìn)入handle處理后,會(huì)調(diào)用對(duì)應(yīng)的auth方法强窖,并傳遞$auth參數(shù)
$client->__setSoapHeaders([$header]);
$link1 = $client->domainLink("9ong",'www.9ong.com');
$link2 = $client->__soapCall('domainLink', ['9ong', 'www.9ong.com']);
echo $link1.'<br />';
echo $link2.'<br />';
print_r($client->getServerInfo());
print_r($client->__getLastRequestHeaders());
}catch(SOAPFault $e){
echo "ERROR:".$e->getMessage();
}
輸出
<a href=www.9ong.com>9ong</a>
<a href=www.9ong.com>9ong</a>
Array
(
[HTTP_AUTHORIZATION] => Basic am06Y2hpbmVzZQ==
[HTTP_CONTENT_LENGTH] => 587
[HTTP_SOAPACTION] => "soap/soapServer#getServerInfo"
[HTTP_CONTENT_TYPE] => text/xml; charset=utf-8
[HTTP_USER_AGENT] => PHP-SOAP/7.1.26
...
[DOCUMENT_ROOT] => /var/www/html/php-shiyanchang
[DOCUMENT_URI] => /FunctionsReference/soap/soapServer.php
[REQUEST_URI] => /FunctionsReference/soap/soapServer.php
[SCRIPT_NAME] => /FunctionsReference/soap/soapServer.php
[CONTENT_LENGTH] => 587
[CONTENT_TYPE] => text/xml; charset=utf-8
[REQUEST_METHOD] => POST
[QUERY_STRING] =>
[SCRIPT_FILENAME] => /var/www/html/php-shiyanchang/FunctionsReference/soap/soapServer.php
[PATH_INFO] =>
[FCGI_ROLE] => RESPONDER
[PHP_SELF] => /FunctionsReference/soap/soapServer.php
[PHP_AUTH_USER] => jm
[PHP_AUTH_PW] => chinese
)
POST /FunctionsReference/soap/soapServer.php HTTP/1.1
Host: demo.130.com
Connection: Keep-Alive
User-Agent: PHP-SOAP/7.1.26
Content-Type: text/xml; charset=utf-8
SOAPAction: "soap/soapServer#getServerInfo"
Content-Length: 587
Authorization: Basic am06Y2hpbmVzZQ==
關(guān)于soapHeader的用途
$header = new SOAPHeader("soap/header", 'auth', $auth, false,SOAP_ACTOR_NEXT);//SOAP_ACTOR_NEXT:soap服務(wù)端接收到請(qǐng)求并進(jìn)入handle處理后凸椿,會(huì)調(diào)用對(duì)應(yīng)的auth方法,并傳遞$auth參數(shù)
上面的范例中翅溺,我們看到handler中的auth方法在server端接收到請(qǐng)求后就會(huì)執(zhí)行脑漫,這個(gè)是為什么呢?我們看鳥哥怎么說(shuō)的:
<div name="section_div" style="background-color:#f5f5dc;padding:5px 5px;width:100%;border-radius:5px;margin-top:15px;"><div><p><font size=3 style="color:black;"><a target="_blank" style="color:black;">使用SoapHeader實(shí)現(xiàn)Soap請(qǐng)求驗(yàn)證 - 風(fēng)雪之隅</a></font></p></div><div style="display:flex;display:-webkit-flex;"><div style="width:50px;"><img style="width:50px;" src="https://www.laruence.com/favicon.ico" /></div><div style="flex:1;-webkit-flex:1;padding-left:10px;overflow:hidden;"><font size=2 color=grey>在PHP的Soap Extension中, 對(duì)于SoapServer來(lái)說(shuō), 并沒(méi)有方法可用得到/處理客戶端發(fā)送的SoapHeader信息. 網(wǎng)上也有很多人認(rèn)為, 只能通過(guò)讀取POST過(guò)來(lái)的請(qǐng)求XML文件, 分析, 才能得到客戶端發(fā)送過(guò)來(lái)的SoapHeader. 但, 其實(shí)在SoapServer端, 其實(shí)是有一種辦法, 可用把SoapHeader當(dāng)作一個(gè)請(qǐng)求來(lái)處理, 從而獲取到客戶端提交的SoapHeader信息.</font></div></div></div><br />
還有人在用SOAP嗎
zhuzhibin 2020-01-10 20:48:58 +08:00
我之前對(duì)接過(guò)未巫。窿撬。自己封裝了一層 W ebservice SOAP 來(lái)處理請(qǐng)求, 有點(diǎn)不太習(xí)慣了,因?yàn)槎际腔?xml 描述叙凡,現(xiàn)在大多數(shù)都是 json 了劈伴,還是挺難受的
Tn5ohB1Yecdk3qCK 2020-01-10 18:39:39 +08:00
天氣,電視節(jié)目 等等好像都是用的 webservice
CHENJIAJIE 2020-01-10 18:35:55 +08:00
電視端的節(jié)目媒資注入都是用 webservice
murmur 2020-01-10 17:03:18 +08:00
我們的一些老接口還是 webservice,新接口已經(jīng)讓外包商用 json 了
zhuzhibin 2020-01-10 20:48:58 +08:00
我之前對(duì)接過(guò)。跛璧。自己封裝了一層 W ebservice SOAP 來(lái)處理請(qǐng)求, 有點(diǎn)不太習(xí)慣了严里,因?yàn)槎际腔?xml 描述,現(xiàn)在大多數(shù)都是 json 了追城,還是挺難受的
Revenant 2020-01-10 23:45:34 +08:00
醫(yī)保平臺(tái)接口都還是走 WebService 的形式呢
yangsh 2020-01-10 23:15:44 +08:00
有刹碾,我們 現(xiàn)在的產(chǎn)品內(nèi)部還在廣泛的使用 webservice
jiashun 2020-01-11 10:36:27 +08:00
國(guó)家電網(wǎng)內(nèi)的異構(gòu)系統(tǒng)集成基本上都是走 ESB,各服務(wù)廠商提供 WebService 集成接口在 ESB 上進(jìn)行注冊(cè)座柱。
至于“WebService 的連接超時(shí)迷帜,和讀取超時(shí)問(wèn)題”,調(diào)用 webservice 接口的時(shí)候可以使用 soap 工具類色洞,設(shè)置連接超時(shí)和讀取超時(shí)參數(shù)戏锹; webservice 接口調(diào)用也可以使用 http 的方式,根據(jù) wsdl 描述來(lái)手工拼裝 webservice 報(bào)文火诸,用 http 工具類進(jìn)行 http 請(qǐng)求锦针。
cway 2020-01-11 12:43:37 +08:00
很多 SAP ERP 系統(tǒng)都還是用 WebService 呢
國(guó)企最多
hantsy 2020-01-11 12:20:25 +08:00 ?? 1
@fox0001 1. SOA 是企業(yè)開(kāi)發(fā)為目標(biāo)的產(chǎn)物。2 SOA 很大程度上想解決各應(yīng)用服務(wù)器供應(yīng)的技術(shù)上互操作問(wèn)題置蜀,SUN奈搜,IBM,還 MS 都是在 SOAP盯荤,SOA 付出很出馋吗。結(jié)果很多東西還是各自為政(如 MS 有很多擴(kuò)展沒(méi)辦法在 Java 平臺(tái)用,SUN 有業(yè)務(wù)流程上有 JBI廷雅,與 BPEL 不兼容耗美,IBM 搞了自己的 SCA ),沒(méi)有達(dá)到預(yù)期的效果航缀。
CHYK 2020-01-10 16:10:13 +08:00
有,僅在單位內(nèi)網(wǎng)的項(xiàng)目上堰怨,對(duì)外則是微服務(wù)了芥玉。
原文:
PHP函數(shù)參考32-一次清楚SOAP擴(kuò)展 - 9ong
PHP函數(shù)參考33-一次清楚RPC框架Yar - 9ong