SOAP
在线手册:中文 英文
PHP手册

The SoapServer class

(No version information available, might only be in SVN)

简介

The SoapServer class provides a server for the » SOAP 1.1 and » SOAP 1.2 protocols. It can be used with or without a WSDL service description.

类摘要

SoapServer {
/* 方法 */
public void addFunction ( mixed $functions )
public void addSoapHeader ( SoapHeader $object )
public __construct ( mixed $wsdl [, array $options ] )
public void fault ( string $code , string $string [, string $actor [, string $details [, string $name ]]] )
public array getFunctions ( void )
public void handle ([ string $soap_request ] )
public void setClass ( string $class_name [, mixed $args [, mixed $... ]] )
public void setObject ( object $object )
public void setPersistence ( int $mode )
public SoapServer ( mixed $wsdl [, array $options ] )
}

Table of Contents


SOAP
在线手册:中文 英文
PHP手册
PHP手册 - N: The SoapServer class

用户评论:

php1221 at klox dot net (18-Aug-2011 09:39)

While there are plenty of mentions online that SoapServer doesn't support SOAP Headers, this isn't true.

In your class, if you declare a function with the name of the header, the function will be called when that header is received.

<?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;
      }
    }
  }

 
funstion MySoapRequest($request) {
    if (
$user_is_valid) {
     
// process request
   
}
    else {
      throw new
MyFault("MySoapRequest", "User not valid.");
    }
  }
}
?>

tom at samplonius dot org (19-Mar-2011 01:45)

Mentions on this page of:

require 'SOAP/SoapServer.php'

are actually referring to PEAR SOAP, not PHP SOAP.  This is the PHP SOAP page.

hawky83 at googlemail dot com (21-Jan-2011 10:46)

Another simple example for SOAP_SERVER with errorhandling an params and wsdl:

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 ();
  }
}

?>

CLIENT (soap_all_client.php) (for 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-Obj.
$proxy = $sw->getProxy ();

// servicemthod
$erg = $proxy->now ("H:i:s");

// return
print $erg."\n";

?>

mikkel at nsales dot dk (02-Jun-2010 11:15)

If you want to return a custom object array from a nusoap webservice, you have to cast the objects to arrays like so:

<?php
$users
= array();
while(
$res = $db_obj->fetch_row())
{
 
$user = new user();
 
$user->Id = $res['id'];
 
$user->Username = $res['username'];
 
$user->Email = $res['email'];
 
 
$users[] = (array) $user;
}

return (
$users);
?>

junk2cm at gmx dot de (25-May-2010 08:54)

As the SoapServer class lacks the possibility of dealing with SOAP-Headers, my following workaround is suitable to my needs when I had to do authentication via the SOAP-Headers:
1. Use a class which handles SOAP requests and let the constructor of this class take the sent headers.
2. Before invoking the SoapServer extract the SOAP-Header from the incoming raw data.
3. When using setClass pass the extracted header to the handling class.

In Your Server-Skript do things like this
<?php
$hdr
= file_get_contents("php://input");
if (
strpos($hdr,'<s:Header>')===false) {
   
$hdr = null;
} else {
   
$hdr = explode('<s:Header>',$hdr);
   
$hdr = explode('</s:Header>',$hdr[1]);
   
$hdr = $hdr[0];
}
$srv = new SoapServer('Your_wsdl');
$srv->setClass("ServiceClass",$hdr);
$srv->handle();
?>

And the service class is like this:
<?php
class ServiceClass {
    var
$IsAuthenticated;

    function
__construct($hdr) {
       
$this->IsAuthenticated = false;
        if (
$hdr!=null) {
           
$this->header = simplexml_load_string($hdr);
           
//Your authentication stuff goes here...
       
}
    }
   
    function
SomeFunctionOfTheService($a) {
        if (
$this->IsAuthenticated) {
           
//here Your function...
       
}
    }

}
?>

carlos dot vini at gmail dot com (20-May-2010 09:55)

SoapServer does not support WSDL with literal/document. I have a class:

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

To fix this I had to create proxy class:
<?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);
   }
}
?>

Now make sure that the WSDL is created using My_Soap. And that the Server is created using My_Soap_LiteralDocumentProxy:

<?php

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

?>

dsubar at interna dot com (26-Dec-2009 05:49)

Do not put a SoapServer and a SoapClient in the same PHP file. This seems to cause arbitrary behavior. On the PHP interpreter in Eclipse, everything worked fine. Under MAMP, I got an undocumented error. In moving the client from the same file as the server, everything worked fine.