PHP SoapClient():发送";“用户代理”;以及“;接受“;HTTP标头


PHP SoapClient(): send "User-Agent" and "Accept" HTTP Header

由于防火墙审核,请求必须始终具有"UserAgent"answers"Accept"标头。

我试过这个:

$soapclient = new soapclient('http://www.soap.com/soap.php?wsdl',
    array('stream_context' => stream_context_create(
        array(
            'http'=> array(
                'user_agent' => 'PHP/SOAP',
                'accept' => 'application/xml')
            )
        )
    )
);

服务器soap 接收到的请求

GET /soap.php?wsdl HTTP/1.1
Host: www.soap.com
User-Agent: PHP/SOAP
Connection: close

预期结果

GET /soap.php?wsdl HTTP/1.1
Host: www.soap.com
Accept application/xml
User-Agent: PHP/SOAP
Connection: close

为什么没有发送"Accept"?"用户代理"有效!

SoapClient构造函数在生成请求标头时不会读取所有stream_context选项。但是,您可以在http:内的header选项中的单个字符串中放置任意标头

$soapclient = new SoapClient($wsdl, [
    'stream_context' => stream_context_create([
        'user_agent' => 'PHP/SOAP',
        'http'=> [
            'header' => "Accept: application/xml'r'n
                         X-WHATEVER: something"               
        ]
    ])
]);

若要设置多个,请使用'r'n将它们分隔开。

(正如Ian Phillips所提到的,"user_agent"可以放在stream_context的根目录下,也可以放在"http"部分内。)

根据PHP SoapClient手册页面,user_agent是一个顶级选项。所以你应该这样修改你的例子:

$soapclient = new SoapClient('http://www.soap.com/soap.php?wsdl', [
    'stream_context' => stream_context_create([
        'http' => ['accept' => 'application/xml'],
    ]),
    'user_agent' => 'My custom user agent',
]);

如果你想让你的代码更灵活,就使用这个。

$client = new SoapClient(
            dirname(__FILE__) . "/wsdl/" . $env . "/ServiceAvailabilityService.wsdl",
            array(
                'login' => $login,
                'password' => $password
            )
        );
        //Define the SOAP Envelope Headers
        $headers = array();
        $headers[] = new SoapHeader(
            'http://api.com/pws/datatypes/v1',
            'RequestContext',
            array(
                'GroupID' => 'xxx',
                'RequestReference' => 'Rating Example',
                'UserToken' => $token
            )
        );
//Apply the SOAP Header to your client
$client->__setSoapHeaders($headers);

也许您可以使用fsockopen()方法来实现这一点像这个

<?php
$sock = fsockopen('127.0.0.1' /* server */, 80 /* port */, $errno, $errstr, 1);
$request = "<Hello><Get>1</Get></Hello>";
fputs($sock, "POST /iWsService HTTP/1.0'r'n");
fputs($sock, "Content-Type: text/xml'r'n");
fputs($sock, "Content-Length: ".strlen($request)."'r'n'r'n");
fputs($sock, "$request'r'n");
$buffer = '';
while($response = fgets($request, 1024)){
    $buffer .= $response;
}
// Then you can parse that result as you want
?>

现在,我手动使用该方法从指纹机中获取SOAP数据。