Hi there,
I'm not member of the PHP community, but ...
I have a proposal to add one new optional boolean paramter for
SoapServer::handle method.
to allow control whether result is sent directly to output (true) or to
string (false).
Default value should be always true for backward compatibility.
This small change will allow to enchance SoapServer implementation and add
support for attachements. I tested it with PHP 5.3, 5.4 and it works great
for me. Now I use it in all my PHP compilations.
Below you'll find required code changes in hadle method and sample class
that implements Soap response with attacheemnt (both MTOM and SWA)
Cheers,
Krzysztof
C code change is very simple:
zend_bool output = 1;
....
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sb", &arg,
&arg_len, &output) == FAILURE) {
return;
}
....
/* Flush buffer */
php_end_ob_buffer(0, 0 TSRMLS_CC);
if (doc_return) {
/* xmlDocDumpMemoryEnc(doc_return, &buf, &size,
XML_CHAR_ENCODING_UTF8); */
xmlDocDumpMemory(doc_return, &buf, &size);
if (size == 0) {
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Dump memory failed");
}
if(output){
..... standard output handling
} else {
RETURN_STRINGL((char*)buf, size, 1);
xmlFreeDoc(doc_return);
xmlFree(buf);
}
} else {
sapi_add_header("HTTP/1.1 202 Accepted", sizeof("HTTP/1.1 202
Accepted")-1, 1);
sapi_add_header("Content-Length: 0", sizeof("Content-Length: 0")-1,
1);
}
class SWASOAPServer extends SoapServer {
var $_executor = null;
function echoSWAHeader($id){
header("MIME-Version: 1.0");
header("Content-Type: Multipart/Related; boundary=MIME_boundary;
type=text/xml; start=<$id>");
header("Content-Description: PHP Soap Server Response SWA.");
}
function echoMTOMHeader($id){
header("MIME-Version: 1.0");
header("Content-Type: Multipart/Related; boundary=MIME_boundary;
type="application/xop+xml"; start="<$id>"; start-info="text/xml";
charset=UTF-8");
header("Content-Description: PHP Soap Server Response MTOM.");
}
function echoMTOMSoap($soap, $id){
$this->echoMimeContent($soap, "application/xop+xml; charset=UTF-8;
type="text/xml";", "binary", $id);
}
function echoSWASoap($soap, $id){
$this->echoMimeContent($soap, "text/xml; charset=UTF-8", "8bit",
$id);
}
function echoMimeContent($content, $mime, $encoding, $id){
echo "--MIME_boundary\n";
echo "Content-Type: $mime\n";
echo "Content-Transfer-Encoding: $encoding\n";
echo "Content-ID: <$id>\n\n";
echo $content;
echo "\n\r";
}
function echoMimeEnd(){
echo "--MIME_boundary--\n";
}
function handle($input,$toOutput = false){
global $config;
$result = parent::handle($input, $toOutput);
if($this->_executor->attachements !=null){
if(strcmp($config['attachement_type'],'mtom')==0){
$id = '0.'.microtime(true);
$this->echoMTOMHeader($id);
$this->echoMTOMSoap($result, $id);
} else {
$id = '0.'.microtime(true);
$this->echoSWAHeader($id);
$this->echoSWASoap($result, $id);
}
foreach($this->_executor->attachements as $id => $attachement){
$this->echoMimeContent($attachement,
$this->_executor->attachements_ctt[$id], 'binary', $id);
}
$this->echoMimeEnd();
} else {
/if ($soap_version == SOAP_1_2) {
//header("Content-Type: application/soap+xml;
charset=utf-8");
} else {/
header("Content-Type: text/xml; charset=utf-8");
/}/
echo $result;
}
}
function setExecutor($executor){
$this->_executor = $executor;
}
}
From: krzysztof karasek [mailto:karasek.krzysztof@gmail.com]
Hi there,
I'm not member of the PHP community, but ...
I have a proposal to add one new optional boolean paramter for
SoapServer::handle method.
to allow control whether result is sent directly to output (true) or to
string (false).
Default value should be always true for backward compatibility.This small change will allow to enchance SoapServer implementation and add
support for attachements. I tested it with PHP 5.3, 5.4 and it works great
for me. Now I use it in all my PHP compilations.
Hi Krzysztof,
I am not sure whether I understand you correctly, but couldn't you use ob_start()
and ob_get_clean()
to get the output of SoapServer::handle() as string.
Here's an example:
class SWASOAPServer extends SoapServer
{
public function handle($input, $toOutput = false){
ob_start()
;
parent::handle($input);
$result = ob_get_clean()
;
// now do something with the output
}
}