PHP函數(shù)參考32-一次清楚SOAP擴(kuò)展


原文:
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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者备图。
  • 序言:七十年代末灿巧,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子揽涮,更是在濱河造成了極大的恐慌抠藕,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蒋困,死亡現(xiàn)場(chǎng)離奇詭異盾似,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)雪标,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門零院,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)溉跃,“玉大人,你說(shuō)我怎么就攤上這事告抄∽ィ” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵打洼,是天一觀的道長(zhǎng)龄糊。 經(jīng)常有香客問(wèn)我,道長(zhǎng)募疮,這世上最難降的妖魔是什么炫惩? 我笑而不...
    開(kāi)封第一講書人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮酝锅,結(jié)果婚禮上诡必,老公的妹妹穿的比我還像新娘。我一直安慰自己搔扁,他們只是感情好爸舒,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著稿蹲,像睡著了一般扭勉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上苛聘,一...
    開(kāi)封第一講書人閱讀 51,763評(píng)論 1 307
  • 那天涂炎,我揣著相機(jī)與錄音,去河邊找鬼设哗。 笑死唱捣,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的网梢。 我是一名探鬼主播震缭,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼战虏!你這毒婦竟也來(lái)了拣宰?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤烦感,失蹤者是張志新(化名)和其女友劉穎巡社,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體手趣,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡晌该,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片气笙。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡次企,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出潜圃,到底是詐尸還是另有隱情缸棵,我是刑警寧澤,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布谭期,位于F島的核電站堵第,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏隧出。R本人自食惡果不足惜踏志,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望胀瞪。 院中可真熱鬧针余,春花似錦、人聲如沸凄诞。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)帆谍。三九已至伪朽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間汛蝙,已是汗流浹背烈涮。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留窖剑,地道東北人坚洽。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像西土,于是被迫代替她去往敵國(guó)和親酪术。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容