PHP overriding “Soapaction” header

Oh no, SOAP again. I hate SOAP…. but making shit work is everyone’s job. So, here i go again. This time i need (don’t ask why) to change the Soapaction header. It turns out to be quite simple with the bundled Soap extension of PHP. Just need to extend the SoapClient and override the  __doRequest function. The code:

<?

class CustomSoapClient extends SoapClient {
  function __doRequest($request, $location, $action, $version, $one_way = 0) {
    $action = 'my_custom_soap_action'; // override soapaction here
    return parent::__doRequest($request, $location, $action, 
                               $version, $one_way);
  }
}


$options = array('exceptions'=>true,
                 'trace'=>1,
                 'cache_wsdl'=>WSDL_CACHE_NONE
                 );
            
$client = new CustomSoapClient('my.wsdl', $options);

try {
  $input = new stdClass();
  $input->property  = "example";
  $input->property2 = "example2";
   
  $response = $client->helloWorld($input);   
   
} catch (Exception $e) {
  echo "\n";
  echo 'Caught exception: ',  $e->getMessage(), "\n";
  echo "\n";
  echo "REQUEST:\n" . $client->__getLastRequestHeaders() .
                      $client->__getLastRequest() . "\n";
  echo "\n";
  echo "RESPONSE:\n" . $client->__getLastResponseHeaders() . 
                       $client->__getLastResponse() . "\n";   
}			
			
?>

Why i hate SOAP

I hate SOAP (not the washing product, but the Simple Object Access Protocol). In theory is very good, a xml document, the WSDL, makes the description of the service, with the valid (and expected) data types, operations and bindings. You just load this WSDL thing in your client, and voilá, you should now automagically have a full feature client to the service, right? Wrong….

Everytime i need to (have to) use a SOAP webservice, there is always something, some tweak, some unexpexted problem to solve. Or is the WSDL format, or is the protocol version, or there is some kind of obscure authentication to do, or encryption, or something with the namespaces in the request, or something…. So, the expected 5 minutes to go, usually turns more into 50 minutes to go, with a lot of traces, network dumps and the works.

Now comes the plain dumbness. Maybe 50% or more of the operations are quite simple, you pass a couple of values and get a simple data back (like a number or a string), and 90% or more of the operations, the request is quite simple, some strings and numbers acting as filters, and the response is a structured data. So, in all this situations you were much better off with a simple REST interface with GET/POSTs to a JSON response. Light, simple and elegant.

Not with this over bloated protocol, with all the tweaks, versions, revisions and recommendations, messy client/servers, excessive formality. You can grasp how bad it is, simply by looking at a typical SOAP session (request/response), there you find that most of the bytes that are going back and forth are not the actual data, but the SOAP envelope, body, header, xml tags, etc….  its like you are working for the protocol and not the other way around.

No surprise it was developed by Microsoft….