添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

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

__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)

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'

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);

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.

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.

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. – user308891 May 30, 2011 at 18:10 Oh, HTTP headers! Sorry about that :) nuSOAP supports cookies, but you'd have to modify it to add headers. – igorw May 30, 2011 at 18:36

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.