I’m using WSO2 WS Framework and I managed to run example in which web service returns an image as a MTOM attachment which is then saved by the client using file_put_contents(…) command.
Service:
<?php
function sendAttachment($msg){
$responsePayloadString = <<<XML
<ns1:download xmlns:ns1="http://wso2.org/wsfphp/samples/mtom">
<ns1:fileName>test.jpg</ns1:fileName>
<ns1:image xmlmime:contentType="image/jpeg" xmlns:xmlmime="http://www.w3.org/2004/06/xmlmime">
<xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:myid1"></xop:Include>
</ns1:image>
</ns1:download>
XML;
$f = file_get_contents("test.jpg");
$responseMessage = new WSMessage($responsePayloadString,
array( "attachments" => array("myid1" => $f)));
return $responseMessage;
}
$operations = array("download" => "sendAttachment");
$service = new WSService(array("operations" => $operations, "useMTOM" => TRUE));
$service->reply();
?>
Client:
<?php
$requestPayloadString = '<download></download>';
try {
$client = new WSClient(
array( "to" => "http://SPLINTER/MTOM/service.php",
"useMTOM" => TRUE,
"responseXOP" => TRUE));
$requestMessage = new WSMessage($requestPayloadString);
$responseMessage = $client->request($requestMessage);
printf("Response = %s \n", $responseMessage->str);
$cid2stringMap = $responseMessage->attachments;
$cid2contentMap = $responseMessage->cid2contentType;
$imageName;
if($cid2stringMap && $cid2contentMap){
foreach($cid2stringMap as $i=>$value){
$f = $cid2stringMap[$i];
$contentType = $cid2contentMap[$i];
if(strcmp($contentType,"image/jpeg") ==0){
$imageName = $i."."."jpg";
if(stristr(PHP_OS, 'WIN')) {
file_put_contents($imageName, $f);
}else{
file_put_contents("/tmp/".$imageName, $f);
}
}
}
}else{
printf("attachments not received ");
}
} catch (Exception $e) {
if ($e instanceof WSFault) {
printf("Soap Fault: %s\n", $e->Reason);
} else {
printf("Message = %s\n",$e->getMessage());
}
}
?>
Instead of that I would like to open a "Save dialog" to choose between opening or saving the file. When searching for solution I read about setting heders like:
header('Content-type: application/octet-stream');
header('Content-disposition: attachment; filename="test.jpg"');
But it didn’t work well. "Save dialog" poped up, but when image couldn’t be opened saying that file is empty.
Actually I don’t understand very good how this MTOM attachments thing is working. In client code, I think $f is a string and when I do printf($f) it prints 0(zero) so how can I save this string as an image?
If you want to use that headers, you have to output the file content, not save it somewhere.
The basics is that at the moment you have your whole file content loaded in a variable (and it seems is
$fin your code), you output it instead of write it in a file (as I think you’re doing now). So, the three lines of code I gave you should replace thefile_put_contents()calls.Instead, if you want to save the file in your
/tmpfolder, ok, do it, but then use insteadThis way you redirect the user browser directly to the saved file, and let users do what they want with it.