2024 年 PHP 日本會議

SoapServer 類別

(PHP 5, PHP 7, PHP 8)

簡介

SoapServer 類別提供 » SOAP 1.1» SOAP 1.2 協定的伺服器。它可以在有或沒有 WSDL 服務描述的情況下使用。

類別概要

類別 SoapServer {
/* 屬性 */
私有 ?SoapFault $__soap_fault = null;
/* 方法 */
公開 __construct(?字串 $wsdl, 陣列 $options = [])
公開 addFunction(陣列|字串|整數 $functions):
公開 addSoapHeader(SoapHeader $header):
公開 fault(
    字串 $code,
    字串 $string,
    字串 $actor = "",
    混合 $details = null,
    字串 $name = ""
):
公開 handle(?字串 $request = null):
公開 setClass(字串 $class, 混合 ...$args):
公開 setObject(物件 $object):
公開 setPersistence(int $mode): void
}

屬性

服務

__soap_fault

目錄

新增註解

使用者貢獻的註解 7 則註解

php1221 at klox dot net
13 年前
雖然網路上有很多提到 SoapServer 不支援 SOAP 標頭的說法,但這並非事實。

在您的類別中,如果您宣告一個與標頭名稱相同的函數,則在收到該標頭時將會呼叫該函數。

<?php
class MySoapService {
private
$user_is_valid;

function
MyHeader($header) {
if ((isset(
$header->Username)) && (isset($header->Password))) {
if (
ValidateUser($header->Username, $header->Password)) {
$user_is_valid = true;
}
}
}

function
MySoapRequest($request) {
if (
$user_is_valid) {
// 處理請求
}
else {
throw new
MyFault("MySoapRequest", "使用者無效。");
}
}
}
?>
mail at borisd dot ru
5 年前
如果您想在 Linux 上將虛擬 SoapServer 作為守護程式執行以進行測試,您需要

1. 在您的 wsdl 中設定位置 "localhost:12312/soapServer.php",例如

<wsdl:service name="ServiceName">
<wsdl:port name="ServiceNamePort" binding="tns:ServiceNameBinding">
<soap:address location="https://127.0.0.1:12312/soapServer.php" />
</wsdl:port>
</wsdl:service>

2. 撰寫您的測試伺服器,例如

<?php
/*
* 伺服器
*/
class TestSoapServer
{
public function
getMessage()
{
return
'Hello, World!';
}
}
$options = ['uri' => 'https://127.0.0.1:12312/'];
$server = new SoapServer(null, $options);
$server->setClass('TestSoapServer');
$server->handle();

?>

3. 使用 `php -S localhost:12312` 執行它(在同一個資料夾中)

當您根據 WSDL 發出請求時,它最終會到達您的「伺服器」。
carlos dot vini at gmail dot com
14 年前
SoapServer 不支援 literal/document 格式的 WSDL。我有一個類別

<?php
class My_Soap {
/**
* 返回 Hello World。
*
* @param string $world
* @return string
*/
public function getInterAdmins($world) {
return
'hello' . $world;
}
}
?>

為了修復這個問題,我必須建立一個代理類別
<?php
class My_Soap_LiteralDocumentProxy {
public function
__call($methodName, $args) {
$soapClass = new My_Soap();
$result = call_user_func_array(array($soapClass, $methodName), $args[0]);
return array(
$methodName . 'Result' => $result);
}
}
?>

現在,請確保使用 My_Soap 建立 WSDL,並使用 My_Soap_LiteralDocumentProxy 建立伺服器。

<?php

if (isset($_GET['wsdl'])) {
$wsdl = new Zend_Soap_AutoDiscover(); // 產生 WSDL
$wsdl->setOperationBodyStyle(array(
'use' => 'literal'
));
$wsdl->setBindingStyle(array(
'style' => 'document'
));
$wsdl->setClass('My_Soap');
$wsdl->handle();
} else {
$server = new Zend_Soap_Server('https://127.0.0.1/something/webservice.php?wsdl');
$server->setClass('My_Soap_LiteralDocumentProxy');
$server->handle();
}

?>
softontherocks at gmail dot com
10 年前
我在這個網址 http://softontherocks.blogspot.com/2014/02/web-service-soap-con-php.html 發布了一個 nusoap 網頁服務的完整範例。

其中定義了伺服器和呼叫網頁服務的客戶端。

希望對您有所幫助。
dsubar at interna dot com
14 年前
不要將 SoapServer 和 SoapClient 放在同一個 PHP 檔案中。這似乎會導致不可預期的行為。在 Eclipse 的 PHP 解釋器中,一切正常。在 MAMP 下,我收到一個未記載的錯誤。將客戶端從與伺服器相同的檔案中移出後,一切正常。
s at dumdeedum dot com
11 年前
我當時運行的是 PHP 5.3.2,無論我多麼仔細地構建我的類別/wsdl/客戶端,我都無法讓 SOAP 標頭工作。最終解決問題的方法是更新到最新的 PHP。不知道是不是哪裡有 bug,但保持最新版本總是一個好主意,而且可能會為您省去數週的挫折!
hawky83 at googlemail dot com
13 年前
另一個使用錯誤處理、參數和 wsdl 的 SOAP_SERVER 簡單範例

伺服器 (soap_all_srv.php)

<?php
// PEAR::SOAP einbinden
require_once "SOAP/Server.php";
$skiptrace =& PEAR::getStaticProperty('PEAR_Error', 'skiptrace');
$skiptrace = true;

// Service-Class
class mytimeserv {

// __dispatch_map
public $__dispatch_map = array ();

// In/Out param -> __dispatch_map
public function __construct() {
$this->__dispatch_map["now"] =
array (
"in" => array("format" => "string"),
"out" => array("time" => "string"));
}

// get back __dispatch_map in __dispatch
public function __dispatch($methodname) {

if (isset(
$this->__dispatch_map[$methodname])) {
return
$this->__dispatch_map[$methodname];
}

return
NULL;
}

// servicemthod with parameters
function now ($format) {

// formaterror?
if (($format == null) || (trim($format) == "")) {

// send errormessage
return new SOAP_Fault("Kein Parameter angegeben","0815", "Client");
}

date_default_timezone_set('Europe/Berlin');

$time = date ($format);

// return SOAP-Obj.
return (new SOAP_Value('time','string', $time));
}
}

// service-class
$service = new mytimeserv();

// server
$ss = new SOAP_Server();

// add service with name
$ss->addObjectMap (&$service,"urn:mytimeserv");

// service or wsdl
if (isset($_SERVER["REQUEST_METHOD"])&& $_SERVER["REQUEST_METHOD"] == "POST") {

// postdata -> service
$ss->service ($HTTP_RAW_POST_DATA);

} else {

// wsdl-param in url
if (isset($_SERVER['QUERY_STRING']) && strcasecmp($_SERVER['QUERY_STRING'],'wsdl') == 0) {

// DISCO_Server for WSDL
require_once "SOAP/Disco.php";
$disco = new SOAP_DISCO_Server ($ss,"mytimeserv","My Time Service");

// set HTML-Header
header("Content-type: text/xml");

// return wsdl
print $disco->getWSDL ();
}
}

?>

客戶端 (soap_all_client.php) (wsdl:http://example.com/soap_all_srv.php?wsdl)
<?php

require_once "SOAP/Client.php";

// SOAP/WSDL
$sw = new SOAP_WSDL ("http://example.com/soap_all_srv.php?wsdl");

// Proxy 物件
$proxy = $sw->getProxy ();

// 服務方法
$erg = $proxy->now ("H:i:s");

// 回傳值
print $erg."\n";

?>
To Top