14

I am doing some work writing a PHP-based SOAP client application that uses the SOAP libraries native to PHP5. I need to send a an HTTP cookie and an additional HTTP header as part of the request. The cookie part is no problem:

Code:

$client = new SoapClient($webServiceURI, array("exceptions" => 0, "trace" => 1, "encoding" => $phpInternalEncoding));
$client->__setCookie($kkey, $vvalue);

My problem is the HTTP header. I was hoping there would have been a function named

__setHeader

or

__setHttpHeader

in the SOAP libraries. But no such luck.

Anyone else dealt with this? Is there a workaround? Would a different SOAP library be easier to work with? Thanks.

(I found this unanswerd question here http://www.phpfreaks.com/forums/index.php?topic=125387.0, I copied it b/c i've the same issue)

5 Answers 5

30

Try setting a stream context for the soap client:

$client = new SoapClient($webServiceURI, array(
    "exceptions" => 0, 
    "trace" => 1, 
    "encoding" => $phpInternalEncoding,
    'stream_context' => stream_context_create(array(
        'http' => array(
            'header' => 'SomeCustomHeader: value'
        ),
    )),
));
Sign up to request clarification or add additional context in comments.

Comments

4

This answer is the proper way to do it in PHP 5.3+ SoapClient set custom HTTP Header

However, PHP 5.2 does not take all of the values from the stream context into consideration. To get around this, you can make a subclass that handles it for you (in a hacky way, but it works).

class SoapClientBackport extends SoapClient {
  public function __construct($wsdl, $options = array()){
    if($options['stream_context'] && is_resource($options['stream_context'])){
      $stream_context_options = stream_context_get_options($options['stream_context']);
      $user_agent = (isset($stream_context_options['http']['user_agent']) ? $stream_context_options['http']['user_agent'] : "PHP-SOAP/" . PHP_VERSION) . "\r\n";
      if(isset($stream_context_options['http']['header'])){
        if(is_string($stream_context_options['http']['header'])){
          $user_agent .= $stream_context_options['http']['header'] . "\r\n";
        }
        else if(is_array($stream_context_options['http']['header'])){
          $user_agent .= implode("\r\n", $stream_context_options['http']['header']);
        }
      }
      $options['user_agent'] = $user_agent;
    }
    parent::__construct($wsdl, $options);
  }
}

1 Comment

I even had to do this with PHP 5.3.10.
4

I ran into a situation where I had to provide a hash of all the text of the soap request in the HTTP header of the request for authentication purposes. I accomplished this by subclassing SoapClient and using the stream_context option to set the header:

class AuthenticatingSoapClient extends SoapClient {
    private $secretKey = "secretKeyString";
    private $context;

    function __construct($wsdl, $options) {
        // Create the stream_context and add it to the options
        $this->context = stream_context_create();
        $options = array_merge($options, array('stream_context' => $this->context));

        parent::SoapClient($wsdl, $options);
    }

    // Override doRequest to calculate the authentication hash from the $request. 

    function __doRequest($request, $location, $action, $version, $one_way = 0) {
        // Grab all the text from the request.
        $xml = simplexml_load_string($request);
        $innerText = dom_import_simplexml($xml)->textContent;

        // Calculate the authentication hash. 
        $encodedText = utf8_encode($innerText);
        $authHash = base64_encode(hash_hmac("sha256", $encodedText, $this->secretKey, true));

        // Set the HTTP headers.
        stream_context_set_option($this->context, array('http' => array('header' => 'AuthHash: '. $authHash)));

        return (parent::__doRequest($request, $location, $action, $version, $one_way)); 
    }       
}

Maybe someone searching will find this useful.

Comments

0

its easy to implement in nuSoap:

NUSOAP.PHP

add to class nusoap_base:

var additionalHeaders = array();

then goto function send of the same class

and add

foreach ($this->additionalHeaders as $key => $value) {
    $http->setHeader($key, $value);
}

somewhere around (just before)

$http->setSOAPAction($soapaction); (line 7596)

now you can easy set headers:

$soapClient = new nusoap_client('wsdl adress','wsdl');
$soapClient->additionalHeaders = array('key'=>'val','key2'=>'val');

Comments

-2

The SoapClient::__soapCall method has an $input_headers argument, which takes an array of SoapHeaders.

You could also use Zend Framework's SOAP client, which provides an addSoapInputHeader convenience method.

2 Comments

That's for soapheaders but I need / searching for a way to modify the http-header of the request that is generated by the soapclient.
Oh, HTTP headers! Sorry about that :) nuSOAP supports cookies, but you'd have to modify it to add headers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.