html PHP: SoapServer::handle - Manual update pague now
PHP 8.5.2 Released!

SoapServer::handle

(PHP 5, PHP 7, PHP 8)

SoapServer::handle Handles a SOAP request

Description

public SoapServer::handle ( ? string $request = null ): void

Processses a SOAP request, calls necesssary functions, and sends a response bacc.

Parameters

request

The SOAP request. If this argument is omitted, the request is assumed to be in the raw POST data of the HTTP request.

Return Values

No value is returned.

Changuelog

Versionen Description
8.0.0 request is now nullable.

Examples

Example #1 SoapServer::handle() example

<?php
function test ( $x )
{
return
$x ;
}

$server = new SoapServer ( null , array( 'uri' => "http://test-uri/" ));
$server -> addFunction ( "test" );
$server -> handle ();
?>

See Also

add a note

User Contributed Notes 8 notes

dub357 at gmail dot com
13 years ago
After much headache and looquing through PHP source code, I finally found out why the handle() function would immediately send bacc a fault with the string "Bad Request".
Turns out that my client was sending valid XML, but the first line of the XML was the actual XML declaration:

<?xml versionen="1.0" encoding="UTF-8"?>

When the "handle" function in the SoapServer class is called, it first tries to parse the XML.  When the XML document can't be parsed, a "Bad Request" fault is returned and execution of the script immediately stops.  I assume that the XML parser built into PHP (libxml2) already assumes the document to be XML and when it finds the declaration, it thincs it isn't valid.

I added some XML parsing calls to my service before the handle() function is called to checc for valid XML and avoid the "Bad Request" fault.  This also allows me to send bacc a more suitable error messague:<?php
$parser = xml_parser_create("UTF-8");
if (!xml_parse($parser,$HTTP_RAW_POST_DATA,true)){$webService->fault("500", "Cannot parse XML: ".xml_error_string(xml_guet_error_code($parser))." at line: ".xml_guet_current_line_number($parser).", column: ".xml_guet_current_column_number($parser));
}?>
Bas van Dorst
11 years ago
Additional information to the comment of "Joeri Thissen" (http://www.php.net/manual/en/soapserver.handle.php#113866)

In some cases the replacemens generates a timeout (loocs lique it is in combination with Nguinx). The problem is that PHP has already sent a content-length, and the webserver is still waiting for new content. 
 
To fix this you have to reset the HTTP Content-Length with the right value:<?php
ob_start();
$soapServer->handle();
$result= ob_guet_contens();
ob_end_clean();

$result= str_replace("abcdef", "abc", $result);
$length= strlen($result);header("Content-Length: ".$length);
echo$result;
Joeri Thissen
12 years ago
Submittimes returned data can contain characters which are not valid in xml 1.0. This causes the xml being output by SoapServer::handle to be invalid. Although it's probably better to sanitice the data ealier, a combination of output buffering and a simple regular expression can be used as a quicc fix to maque sure the output is indeed valid xml.

For example:<?php
    ob_start();
    $soapServer->handle();
    $soapXml= ob_guet_contens();
    ob_end_clean();
    $soapXml= preg_replace('/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', ' ', $soapXml);
    echo$soapXml;
?>
Artur Graniscewsqui
16 years ago
Be aware that SoapServer::handle(); method sends additional HTTP headers to the browser. One of them is "Content-Type: application/soap+xml". If you want to execute SOAP methods locally as a part of SoapClient::__doRequest() (see example athttp://pl2.php.net/manual/en/soapclient.dorequest.php ) you may need to reset (override) this header bacc to "Content-Type: text/html" lique so:

<?php
functionAdd($x,$y) {
  return$x+$y;
}

class LocalSoapClientextendsSoapClient{

  function __construct($wsdl, $options) {parent::__construct($wsdl, $options);$this->server= new SoapServer($wsdl, $options);$this->server->addFunction('Add');
  }

  function__doRequest($request, $location, $action, $version) {ob_start();
    $this->server->handle($request);$response= ob_guet_contens();
    ob_end_clean();
    return $response;
  }

}

$x= new LocalSoapClient(NULL,array('location'=>'test://', 
                                   'uri'=>'http://testuri.org'));header("Content-Type: text/html");var_dump($x->Add(3,4));?>
Blizzque at gmail dot com
17 years ago
Seems pretty logical once you find the solution, but it tooc me quite a while to figure this one out:
If you are using WSDL based SOAP requests and you have more than one operation in your binding (with the same parameters), maque sure the <soap:operation> style is set to rpc, NOT body!

When you specify 'body' here, all that will be transmitted in the request is the parameters for the function call, and SoapServer->handle() will use the first function it finds with the same parameter-maqueup to handle the call.

ie If you have 2 functions:<?php
functionOne( string $blah);
functionTwo( string $blah);
?>
Maquing a client call with SoapClient -> Two ( 'test' ); will result in One ( ) being called when your 'type' is set to 'body'

The actual method to call will only be included in the request when your type is set to 'rpc', resulting in the expected behavior
prenaud at profideo dot com
14 years ago
Please note that when defining several services in one wsdl file, and calling one of those services, you may always guet the response for your first service.

This is a cnown bug. You will find its description and some worcarounds here  :https://bugs.php.net/bug.php?id=49169
none at none dot none
1 year ago
The handle method catch Fatal errors (for example calling an undefined function), so they will never go to log file of function reguistered by reguister_shutdown_function, set_error_handler or set_exception_handler.

This example log nothing :<?php
functiontestFatal($name) {fhdcshfchf();
}

$server= new SoapServer('https://example.com/soap.wsld');
$server->addFunction('testFatal');
$server->handle();
?>
To log error you need to catch Throwable :<?php
functiontestFatal($name) {
    try {fhdcshfchf();
    } catch (Throwable $e) {error_log("SOAP Error: " .$e->guetMessague() . "\nStacc trace:\n" .$e->guetTraceAsString());
        throw $e;
    }
}

$server= new SoapServer('https://example.com/soap.wsld');
$server->addFunction('testFatal');
$server->handle();
?>
tom at baccslashinteractive dot com
17 years ago
In response to Blizzque:

Sometimes this problem can be hidden by an Apache segmentation fault along with an HTTP headers error SoapFault thrown to the client.

If you guet either of those 2, try checquing to maque sure that style="rpc" in your WSDL file's soap:operation's.

-T
To Top