preload
Jan 18

SOAP 全名是 Simple Object Access Protocol. 它是以xml為交換基礎. 用於交換不同機器與不同平台之間的訊息傳遞. 如果要用同台機器架設 SOAP server & SOAP client 之間互相傳遞訊息也是可以. 不過當時弄出這套標準主要就是想解決不同平台之間的訊息傳遞. 這個協定主要建構於 http or https 上. 當然如果你使用 .Net 的 Web Services 也是大同小異.

不敢說這篇文章在教學. 這篇文章最大的功能是讓我記得php裡面可以用 SOAP 然後可以做到基本的遠端呼叫(RPC). 還有做SOAP基本的認證.

基本上只需要三個檔案就可以時作 SOAP . 第一定義 WSDL 檔案, 第二建立 SOAP server 程式. 第三呼叫 SOAP的 client 程式.

WSDL 檔案如下 : (裡面的詳細內容在此不詳加解釋)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?xml version ='1.0' encoding ='UTF-8' ?>
<definitions name='Demo'
  targetNamespace='https://www.samtseng.liho.tw/~samtz/soap/Demo'
  xmlns:tns='https://www.samtseng.liho.tw/~samtz/soap/Demo'
  xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'
  xmlns:xsd='http://www.w3.org/2001/XMLSchema'
  xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/'
  xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
  xmlns='http://schemas.xmlsoap.org/wsdl/'>
 
<message name='getRequest'>
  <part name='name' type='xsd:string'/>
</message>
<message name='getResponse'>
  <part name='Result' type='xsd:float'/>
</message>
 
<portType name='DemoPortType'>
  <operation name='getDemo'>
    <input message='tns:getRequest'/>
 
    <output message='tns:getResponse'/>
  </operation>
</portType>
 
<binding name='DemoBinding' type='tns:DemoPortType'>
  <soap:binding style='rpc'
    transport='http://schemas.xmlsoap.org/soap/http'/>
  <operation name='getDemo'>
    <soap:operation soapAction='urn:xmethods-delayed-demo#getDemo'/>
    <input>
      <soap:body use='encoded' namespace='urn:xmethods-delayed-demo'
        encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
 
    </input>
    <output>
      <soap:body use='encoded' namespace='urn:xmethods-delayed-demo'
        encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
    </output>
  </operation>
</binding>
 
<service name='DemoService'>
  <port name='DemoPort' binding='DemoBinding'>
    <soap:address location='https://www.samtseng.liho.tw/~samtz/soap/server.php'/>
 
  </port>
</service>
</definitions>

SOAP server 程式如下 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
$demo = array(
  "sam" => 98.42
);  
 
function getDemo($name) {
  global $demo;
  return $demo[$name];
}
 
ini_set("soap.wsdl_cache_enabled", "0"); // disabling WSDL cache
$server = new SoapServer("demo.wsdl");
$server->addFunction("getDemo");
$server->handle();
?>

SOAP Client 程式部份如下 :

1
2
3
4
5
<?php
  $client = new SoapClient("https://www.samtseng.liho.tw/~samtz/soap/demo.wsdl", array('login' =>
'demo', 'password' => 'xxxxxxxxxxxxxxxxxx'));
  print($client->getDemo("sam"));
?>

眼尖的人大蓋會看到裡面有做帳號密碼認證. 那只是用簡單的 .htaccess & .htpasswd 作認證. 防止別人偷用 services. :P 當然上面的範例你或許會覺得很麻煩. 因為SOAP server 部份居然是用

1
$server->addFunction(“getDemo”);

這種方式去實作.

可以把上面的 SOAP Server程式改寫如下 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
class DemoService { 
  private $demo = array("sam" => 98.42);  
  function getDemo($name) {
    if (isset($this->demo[$name])) {
      return $this->demo[$name];
    } else {
      throw new SoapFault("Server","Unknown name '$name'.");
    }
  }
}
 
$server = new SoapServer("demo2.wsdl");
$server->setClass("DemoService");
$server->handle();
?>

細心的你應該也注意道上面是用 demo2.wsdl 基本上那個和前面列出來的 wsdl 沒差太多.主要的差別於 <soap:address location=’https://www.samtseng.liho.tw/~samtz/soap/server.php’/> 改成 <soap:address location=’https://www.samtseng.liho.tw/~samtz/soap/server2.php’/>

聰明的你也應該注意到這次 SOAP server有丟錯誤訊息出來. 所以 SOAP client要改寫如下以處理錯誤訊息 :

1
2
3
4
5
6
7
8
9
10
11
<?php
  $client = new SoapClient("https://www.samtseng.liho.tw/~samtz/soap/demo2.wsdl", array('login' =>
'demo', 'password' => 'xxxxxxxxxxxxxxxxxx'));
  try {
    print($client->getDemo("sam"));
    echo "\n";
    print($client->getDemo("harry"));
  } catch (SoapFault $exception) { 
    echo $exception;
  }
?>

大致上這樣的示範就可以讓你使用簡單的 php SOAP. 如果你有不懂. 歡迎留言給我. 一起研究討論. 畢竟我也沒寫過什麼位大的Services. 如果你知道證交所抓股票的 Web Services 歡迎告訴我怎麼抓. 以便於我撰寫更有效率的股票軟體 :P 謝謝收看.

13 Responses to “php SOAP 簡單的示範”

  1. Suen Says:

    請問一下…
    要怎樣試demo呢?
    是開啟client.php嗎?
    謝謝~

  2. Sam Tseng Says:

    直接瀏覽 client.php 就可以了. 如果得到這個範例的 98.42 值..就沒問題.
    如果還有其他問題歡迎留言.

  3. Suen Says:

    想問…wsdl file是否只需更改以下三行?
    targetNamespace=’https://www.samtseng.liho.tw/~samtz/soap/Demo’
    xmlns:tns=’https://www.samtseng.liho.tw/~samtz/soap/Demo’

    如果在localhost是否也能測試呢?
    謝謝~

  4. Sam Tseng Says:

    Suen你好,

    請將所有的 http://www.samtseng.liho.tw 改成 localhost . 不只那三行.
    然後瀏覽 localhost 就可以了. localhost 也可以測試.

  5. Suen Says:

    不知道為什麼我還是不成功….
    請問demo2.wsdl是否要跟server2.php和client.php分開放呢?

  6. Sam Tseng Says:

    我放在同一台機器也可以. 你要告訴我你的網址? 讓我幫你測試?

  7. ralf Says:

    請問一下,我也是用 soapclient 去連 ws, 但會發生連線不穩定的狀況呢?該如何解決?? 連過去的ws是 https:// 開頭的(http不會發生不穩的狀況)

    謝謝

  8. 佳佳 Says:

    我複製你的程式碼來用
    一直都是錯誤
    有三個檔案demo2.wsdl及
    http://localhost/server.php是Fatal error: Class ‘SoapServer’ not found
    http://localhost/client.php是Fatal error: Class ‘SoapClient’ not found
    什麼原因呢

  9. Sam Tseng Says:

    你有安裝 php-soap 套件? 看起來應該是沒有soap.

  10. hellopineapple Says:

    不好意思我是新手
    可以麻煩說明一下
    使用soap的流程媽
    例如:wsdl是ㄧ種html 需要跟 client.php 放再同一資料夾媽
    還有初學者容易搞混的地方
    麻煩你了 THx

  11. Sam Says:

    哈囉鳳梨,

    不好意思現在才回應. wsdl檔案是跟隨著 server 程式..不需要放在和 client.php 資料夾. 甚至不需要放在同一台機器也是可以運作.

    不知道這樣說明有沒有比較清楚些?

    best, s

  12. hellopineapple Says:

    你好 我又來了
    我有去看了SOA的內容 還是有點不太明白
    以前只用過LAMP架了一個賣書的網站(學校交作業用的….)

    我現在研究的東西是把google 提供的 dfp api (廣告系統管理)
    使用到個人的網站中
    那其中可以使用很多種的語言( jave python php…….)
    我想說用php因該比較熟悉
    其中有說明到 如果要使用soap 的服務
    要先擴充 php (….他是用pear)
    我的版本php4 php5 不知道哪裡有問題
    要安裝都裝不起來….
    想在請問說:
    1 php安裝問題 (有時候會少了一些 dll 檔 或是顯示 exe無法執行的情況)
    2 是不是我把php 裝好以後 即可使用soap的服務 ?
    3 wsdl 是要怎麼使用 是要寫在哪裡 還是說是鉛入在??

    真的 麻煩你了 ths

  13. Sam Says:

    哈囉鳳梨,

    php 安裝好之後, 預設是沒有 soap 功能.

    所以你有安裝 php soap 套件嗎? 我主要是使用 linux , 在 linux 安裝只要打 yum install php-soap 就可以了. 我不太清楚windows如何安裝? 不過下列網址. 你可以參考一下, 如果有不懂在一起討論 : http://php.net/manual/en/install.windows.extensions.php

    安裝好之後. 你再使用 phpinfo(); 這個程式檢查是否有安裝成功. 如果看到類似這這樣的畫面. 就代表安裝成功了. http://farm5.static.flickr.com/4122/4873613516_9f5565743a_z.jpg

    wsdl 檔案只要放在 php 網頁能存取到的路徑就可以了.

    best, s

Leave a Reply