php SOAP 簡單的示範

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. 😛 當然上面的範例你或許會覺得很麻煩. 因為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 歡迎告訴我怎麼抓. 以便於我撰寫更有效率的股票軟體 😛 謝謝收看.