2014-04-29 12 views
11

A causa di un controllo firewall, le richieste devono sempre avere l'intestazione "UserAgent" e "Accept".PHP SoapClient(): invia "User-Agent" e "Accept" HTTP Header

ho provato questo:

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

la richiesta ricevuta dal server di sapone

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

il risultato atteso

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

Perché "Accetta" non è stato inviato? "User-Agent" funziona!

risposta

10

Il costruttore SoapClient non leggerà tutte le opzioni stream_context quando si generano le intestazioni di richiesta. Tuttavia, è possibile inserire intestazioni arbitrarie in una singola stringa in un'opzione header all'interno http:

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

Per impostare più di uno, separarli con \r\n.

(Come già detto da Ian Phillips, il "user_agent" può essere posizionato sia alla radice del stream_context, o all'interno del "http" parte.)

2

Secondo the PHP SoapClient manual page, user_agent è un'opzione di primo livello. Così si dovrebbe modificare l'esempio in questo modo:

$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', 
]); 
0

forse è possibile utilizzare fsockopen() metodo per farlo come questo

<?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 
?> 

Io uso questo metodo manualmente per ottenere i dati SOAP dalla mia macchina per le impronte digitali ora.

+0

ho giù votato come la questione si chiede esplicitamente di usare 'SoapClient' (http://php.net/manual/en/class.soapclient.php) e questo non fornisce alcun aiuto per quanto riguarda la richiesta di . –

2

Se si desidera che il codice sia più flessibile, utilizzare questo.

$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); 
+0

Grazie a tutti –