title: PHP - extending SoapClient to handle SWA (SOAP with Attachment)
body: <p>I'm attempting to handle SWA responses from a Java SOAP service. In that SWA response is a binary attachment(s) appended to the end of the XML along with some MIME headers. I cannot use WSO2 for dependency requirement limitations.</p>
  
  <p>Any help would be much appreciated!</p>
  
  <pre><code>// Input
  
  ------=_Part_42_539586119.1332526191981
  Content-Type: text/xml; charset=UTF-8
  Content-Transfer-Encoding: binary
  Content-Id: &lt;03B4708A9544C182C43E51D9ADA1E456&gt;
  
  &lt;?xml version="1.0" encoding="utf-8"?&gt;&lt;soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;&lt;soapenv:Body&gt; ... TRUNCATED XML SOAP RESPONSE ... &lt;/soapenv:Body&gt;&lt;/soapenv:Envelope&gt;
  
  ------=_Part_42_539586119.1332526191981
  Content-Type: image/png
  Content-Transfer-Encoding: binary
  Content-Id: &lt;D637B1257E3E5EEA06AF0E45494F8448&gt;
  
  BINARY DATA GOES HERE
  
  
  // End of input
  </code></pre>
  
  <p>// Script to split the response + return StdObj's like the parent class SoapClient + do something with the files</p>
  
  <pre><code>namespace Project;
  class SoapClient extends \SoapClient
  {
      public function __call ($function_name, $arguments)
      {
          // have the parent do a soap call, catch the lastResponse() if an error
          // occurred (eg has an attachment) and parse it out.
          try {
              $r = parent::__call($function_name, $arguments);
              return $r;
          } catch (\Exception $e) {
              // Assumption: When this is sent, it means that a file is being sent
              // because SimpleXML can't process it.
              if ($e-&gt;getMessage() == "looks like we got no XML document") {
                  $response = parent::__getLastResponse();
                  $partString = "/(------=_[a-zA-Z0-9_\\.]+)/";
                  $outputArr = preg_split($partString, $response);
                  // $outputAtt[0] -- empty and is the first MIME Part Header
                  // $outputArr[1] -- Mime Header + XML (The SOAP Response)
                  // $outputArr[n+1] -- additional files w/ MIME headers
                  if (array_key_exists(1, $outputArr)) {
                      // remove the first 5 lines (4 MIME Header lines) + 1 Blank
                      // line
                      $data = implode("\n",
                      array_slice(explode("\n", $outputArr[1]), 5));
  
                      /// Simple XML Object ... appears to be an empty SimpleXMLElement though ... &gt;:-(
                      $xml = simplexml_load_string($data, null, null, "http://schemas.xmlsoap.org/soap/envelope/");
  
  
  
  
                  } else {
                      // OK Maybe this doesn't actually contain the XML... throw
                      // the original exception.
                      throw new \SoapFault($e-&gt;getMessage(), $e-&gt;getCode(),
                      $e-&gt;getPrevious());
                  }
              } else {
                  throw new \SoapFault($e-&gt;getMessage(), $e-&gt;getCode(),
                  $e-&gt;getPrevious());
              }
          }
      }
  }
  </code></pre>