PHP и заголовок действия без мыла - PullRequest
5 голосов
/ 22 ноября 2011

Я пытаюсь вызвать удаленный веб-сервис в моей компании.По частным причинам я не могу предоставить URL-адрес веб-службы.Веб-сервис имеет единственную функцию с именем getItemField.Это небольшой тестовый сервис, с которым я пытаюсь запустить PHP, описание сервиса выглядит следующим образом:

<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://www.oracle.com/ws/MyFirstWebService" xmlns:intf="http://www.oracle.com/ws/MyFirstWebService" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns1="http://www.w3.org/1999/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.oracle.com/ws/MyFirstWebService">
<!--
WSDL created by Apache Axis version: 1.2alpha Built on Oct 23, 2007 (12:09:54 IST)
-->
<wsdl:types>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.oracle.com/ws/MyFirstWebService">
<import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
<complexType name="ArrayOf_xsd_string">
<complexContent>
<restriction base="soapenc:Array">
<attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:string[]"/>
</restriction>
</complexContent>
</complexType>
</schema>
</wsdl:types>
<message name="getItemFieldRequest">
<part name="args" type="impl:ArrayOf_xsd_string"/>
</message>
<message name="getItemFieldResponse">
<part name="getItemFieldReturn" type="soapenc:string"/>
</message>
<portType name="MyFirstWebService">
<operation name="getItemField" parameterOrder="args">
<input message="impl:getItemFieldRequest" name="getItemFieldRequest"/>
<output message="impl:getItemFieldResponse" name="getItemFieldResponse"/>
</operation>
</portType>
<binding name="MyFirstWebServiceSoapBinding" type="impl:MyFirstWebService">
<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="getItemField">
<wsdlsoap:operation soapAction=""/>
<input name="getItemFieldRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://first" use="encoded"/>
</input>
<output name="getItemFieldResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://www.oracle.com/ws/MyFirstWebService" use="encoded"/>
</output>
</operation>
</binding>
<service name="MyFirstWebServiceService">
<port binding="impl:MyFirstWebServiceSoapBinding" name="MyFirstWebService">
<wsdlsoap:address location="http://myWebsite.com/services/MyFirstWebService"/>
</port>
</service>
</definitions>

Я могу нормально подключиться к сервису и распечатать имя одной функции итипа, но когда я пытаюсь вызвать функцию, я получаю 'no SOAPAction header!' error.Мой PHP-код для вызова сервисной функции выглядит следующим образом:

$options = array(
                // Dev
                'soap_version'=>SOAP_1_2, 
                'exceptions'=>true, 
                'trace'=>1, 
                'cache_wsdl'=>WSDL_CACHE_NONE,
                'features' => SOAP_SINGLE_ELEMENT_ARRAYS,

                // Credentials
                'login' => 'user', 
                'password' => 'pass'
            );        

// Connected successfully
            $client = new SoapClient( "http://myWebsite.com/services/MyFirstWebService?wsdl", $options );

    //Params
        $params = array( '123456' );

        //Options
        $options = array( 'soapaction' => '""' );

        //Call function (Both methods below throw the same 'no SOAPAction header!' error)
        //$result = $client->getItemField( new SoapParam($params, "getItemFieldRequest") );
        $result = $client->__soapCall( "getItemField", array('123456'), $options );

На основании описания сервиса, похоже, не определено мыло.Строка, которую я вижу с soapAction, <wsdlsoap:operation soapAction=""/>.Я попытался указать пустой soapAction, так как он не определен, но, похоже, это не сработало.Является ли само определение веб-службы неполным?Или я пропускаю какой-либо параметр в моем вызове приложения на стороне клиента?Заранее спасибо.

ОБНОВЛЕНИЕ:

Попытка указать имя метода в качестве действия мыла, но htat не работает.

    //Params
    $params = array( '123456' );

    //Options
    $options = array( 'soapaction' => 'getItemField' );

    //Call function (STILL THROWS 'no SOAPAction header!')
    $result = $client->__soapCall( "getItemField", $params, $options );

Что я должен делатьделать, если в wsdl не указано soapAction, т. е. если установлено значение "".

Ответы [ 2 ]

2 голосов
/ 31 июля 2012

У меня была похожая проблема, но я использовал cURL, а не SoapClient, хотя решение может быть таким же.

Когдаотправляя запрос в конечную службу, вы должны отправить заголовок с указанием Content-Type.В этом заголовке вы также можете указать action, или «действие мыла».

$headers = array();
$headers[] = 'Content-Type: application/soap+xml; charset=utf-8; action="[soap action goes here]"';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

В моем случае, и то, что похоже на ваш, wsdl перечисляет следующее:

<wsdl:operation name="getProducts">
    <soap:operation soapAction=""/>
    <!-- trimmed -->
</wsdl:operation>

Сначала я вижу soapAction="", поэтому я установил action="" в отправляемых заголовках.Это не удалось.Правильные данные, которые входят в заголовок - это operation, что делает его action="getProducts".

На основе руководства для SoapClient и ответа на php с использованием SOAPс другим SoapAction ваш запрос должен был работать с:

$client = new SoapClient( "http://myWebsite.com/services/MyFirstWebService?wsdl", $options );
$result = $client->__soapCall( "getItemField", array('123456') );

Вы когда-нибудь пропускали $options, отправленный на __soapCall(), чтобы просто не указывать действие (вместо того, чтобы пропустить пустоеодин)

0 голосов
/ 22 июня 2012

Трудно помочь, не имея всей необходимой информации, но я посоветую вам попробовать следующее:

//Replace accordingly: see PHP Manual
//(http://www.php.net/manual/en/soapheader.soapheader.php)

$header = new SoapHeader($namespace, $name, $data, $mustunderstand, $actor);
$client->__setSoapHeaders($header);

//Main soap call follows....

перед тем, как позвонить в мыльную службу.Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...