SoapClient 设置自定义 HTTP 标头

发布于 2024-11-10 15:56:59 字数 720 浏览 4 评论 0原文

我正在编写一个基于 PHP 的 SOAP 客户端应用程序,该应用程序使用 PHP5 原生的 SOAP 库。我需要发送一个 HTTP cookie 和一个附加的 HTTP 标头作为请求的一部分。 cookie部分没有问题:

代码:

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

我的问题是HTTP标头。 有一个名为

__setHeader

__setHttpHeader

我希望SOAP 库中 的函数。但没有这样的运气。

还有其他人处理过这个吗?有解决方法吗?不同的 SOAP 库会更容易使用吗?谢谢。

<子> (我在这里发现了这个未回答的问题 http://www.phpfreaks.com/forums/ index.php?topic=125387.0,我复制了它,因为我也有同样的问题)

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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

紅太極 2024-11-17 15:56:59

尝试为肥皂客户端设置流上下文:

$client = new SoapClient($webServiceURI, array(
    "exceptions" => 0, 
    "trace" => 1, 
    "encoding" => $phpInternalEncoding,
    'stream_context' => stream_context_create(array(
        'http' => array(
            'header' => 'SomeCustomHeader: value'
        ),
    )),
));

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'
        ),
    )),
));
琉璃梦幻 2024-11-17 15:56:59

这个答案是在 PHP 5.3+ 中执行此操作的正确方法 SoapClient 设置自定义 HTTP 标头

但是,PHP 5.2 并没有考虑流上下文中的所有值。为了解决这个问题,您可以创建一个子类来为您处理它(以一种黑客的方式,但它有效)。

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

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);
  }
}
别低头,皇冠会掉 2024-11-17 15:56:59

我遇到了一种情况,为了进行身份验证,我必须在请求的 HTTP 标头中提供 SOAP 请求的所有文本的哈希值。我通过子类化 SoapClient 并使用 stream_context 选项设置标题:

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

也许搜索的人会发现这很有用。

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.

暗藏城府 2024-11-17 15:56:59

在nuSoap中很容易实现:

NUSOAP.PHP

添加到类nusoap_base

var additionalHeaders = array();

然后转到同一个类的函数send

并添加到

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

周围的某个地方(只需之前)

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

现在您可以轻松设置标题:

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

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');
表情可笑 2024-11-17 15:56:59

SoapClient::__soapCall 方法有一个 $input_headers 参数,它采用 SoapHeader

您还可以使用 Zend Framework 的 SOAP 客户端,它提供了一个 addSoapInputHeader 便捷方法。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文