PHP Conference Japan 2024

SoapServer 类

(PHP 5、PHP 7、PHP 8)

简介

SoapServer 类提供了一个用于 » SOAP 1.1» SOAP 1.2 协议的服务器。它可以与或不与 WSDL 服务描述一起使用。

类概要

class SoapServer {
/* 属性 */
private ?SoapFault $__soap_fault = null;
/* 方法 */
public __construct(?string $wsdl, array $options = [])
public addFunction(array|string|int $functions): void
public addSoapHeader(SoapHeader $header): void
public fault(
    string $code,
    string $string,
    string $actor = "",
    mixed $details = null,
    string $name = ""
): void
public handle(?string $request = null): void
public setClass(string $class, mixed ...$args): void
public setObject(object $object): void
public setPersistence(int $mode): void
}

属性

service

__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 年前
我在这个 URL http://softontherocks.blogspot.com/2014/02/web-service-soap-con-php.html 发布了一个完整的 nusoap web service 示例。

其中定义了服务器和调用 web service 的客户端。

希望对您有所帮助。
dsubar at interna dot com
14 年前
不要在同一个 PHP 文件中放置 SoapServer 和 SoapClient。这似乎会导致任意行为。在 Eclipse 中的 PHP 解释器上,一切正常。在 MAMP 下,我得到了一个未记录的错误。将客户端从与服务器相同的文件中移出后,一切正常。
s at dumdeedum dot com
11 年前
我当时运行的是 PHP 5.3.2,无论我多么小心地构建我的类/wsdl/客户端,都无法让 SOAP header 工作。最终解决问题的方法是更新到最新的 PHP。不知道是哪里出了问题,但保持最新版本永远不是坏主意,它可能会为你节省数周的沮丧!
hawky83 at googlemail dot com
13 年前
另一个关于 SOAP_SERVER 的简单示例,包含错误处理、参数和 wsdl

服务器 (soap_all_srv.php)

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

// 服务类
class mytimeserv {

// __dispatch_map
public $__dispatch_map = array ();

// 输入/输出参数 -> __dispatch_map
public function __construct() {
$this->__dispatch_map["now"] =
array (
"in" => array("format" => "string"),
"out" => array("time" => "string"));
}

// 在 __dispatch 中获取 __dispatch_map
public function __dispatch($methodname) {

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

return
NULL;
}

// 带参数的服务方法
function now ($format) {

// 格式错误?
if (($format == null) || (trim($format) == "")) {

// 发送错误消息
return new SOAP_Fault("Kein Parameter angegeben","0815", "Client");
}

date_default_timezone_set('Europe/Berlin');

$time = date ($format);

// 返回 SOAP 对象
return (new SOAP_Value('time','string', $time));
}
}

// 服务类
$service = new mytimeserv();

// 服务器
$ss = new SOAP_Server();

// 添加服务并命名
$ss->addObjectMap (&$service,"urn:mytimeserv");

// 服务或 wsdl
if (isset($_SERVER["REQUEST_METHOD"])&& $_SERVER["REQUEST_METHOD"] == "POST") {

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

} else {

// url 中的 wsdl 参数
if (isset($_SERVER['QUERY_STRING']) && strcasecmp($_SERVER['QUERY_STRING'],'wsdl') == 0) {

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

// 设置 HTML 头
header("Content-type: text/xml");

// 返回 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 = $sw->getProxy ();

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

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

?>
To Top