2016-10-24 2 views
1

Я тестирую Некоторые функции Мыло с PHPмыло PHP сила преобразование последовательности в массив PHP

$soapClient = new CustomSoapClient($urlWsdl,[ 
    'exceptions' => true 
    'trace' => true, 
    'location' => $soapUrl 
]); 

$soapResponse = $soapClient->__call('ProfileLookup',$methodArgs) 

CustomSoapClient класс, который расширяет базовый класс SoapClient для входа запроса XML и ответ (в " __doRequest»метод. $ soapUrl является расположение тестирования Soap Server, который способен ответить на метод ProfileLookup, возвращая один или больше результата

WSDL, ($ urlWsdl) определяют этот метод и его типы возвращаемых

<wsdl:operation name="ProfileLookup"> 
     <wsdl:input message="tns:ProfileLookupRequest"/> 
     <wsdl:output message="tns:ProfileLookupResponse"/> 
    </wsdl:operation> 

<wsdl:message name="ProfileLookupResponse"> 
    <wsdl:part name="LookupResponse" element="n:LookupResponse"/> 
</wsdl:message> 

<xs:element name="LookupResponse"> 
    <xs:complexType> 
     <xs:sequence> 
      <xs:element name="Result" type="c:ResultStatus"/> 
      <xs:element name="ProfileLookups" type="tns:ProfileLookupList"/> 
     </xs:sequence> 
    </xs:complexType> 
</xs:element> 

<xs:complexType name="ProfileLookup"> 
    <xs:sequence> 
     <xs:element name="PersonName" type="c:PersonName"/> 
     ... 
    </xs:sequence> 
</xs:complexType> 

<xs:complexType name="ProfileLookupList"> 
    <xs:sequence> 
     <xs:element name="ProfileLookup" type="tns:ProfileLookup" minOccurs="0" maxOccurs="unbounded"/> 
    </xs:sequence> 
</xs:complexType> 

Если я называю веб-службы, и что это один возвращать несколько результатов, XML Возвращается OK

<env:Body> 
     <ns1:LookupResponse> 
      <ns1:Result resultStatusFlag="SUCCESS"/> 
      <ns1:ProfileLookups> 
       <ns1:ProfileLookup> 
        <ns1:PersonName> 
        </ns1:PersonName> 
       </ns1:ProfileLookup> 
       <ns1:ProfileLookup> 
        <ns1:PersonName> 
        </ns1:PersonName> 
       </ns1:ProfileLookup> 
      </ns1:ProfileLookups> 
     </ns1:LookupResponse> 
    </env:Body> 

и это, как этот ответ преобразуется в PHP

[ProfileLookups] => stdClass Object (
    [ProfileLookup] => Array(
      [0] => stdClass Object (
       [PersonName] => stdClass Object() 
      ), 
      [1] => stdClass Object (
       [PersonName] => stdClass Object() 
      ) 
    ) 
) 

Если я позвоню веб-сервис, чтобы получить только один результат, я получаю одну и ту же структуру xml

<env:Body> 
      <ns1:LookupResponse> 
       <ns1:Result resultStatusFlag="SUCCESS"/> 
       <ns1:ProfileLookups> 
        <ns1:ProfileLookup> 
         <ns1:PersonName> 
         </ns1:PersonName> 
        </ns1:ProfileLookup> 
       </ns1:ProfileLookups> 
      </ns1:LookupResponse> 
     </env:Body> 

Но con версия для значения PHP отличается:

[ProfileLookups] => stdClass Object (
    [ProfileLookup] => stdClass Object(
     [PersonName] => stdClass Object() 
    ) 
    ) 

Как вы видите, в первом Exemple, ProfileLookup представляет собой массив объектов типа «ProfileLookup», во втором один ProfileLookup сам по себе является объектом типа «ProfileLookup».

Таким образом, следующий код приведет к ошибкам, если возвращается только один элемент.

foreach($soapResponse->ProfileLookups->ProfileLookup as $profileLookup){ 
    echo $profileLookup->PersonName->... 
} 

Поэтому, конечно, я мог бы легко протестировать, если ProfileLookups-> ProfileLookup является массивом или объектом, а затем заставить его быть массивом. но это не похоже на правильный путь, поскольку я могу столкнуться с этой проблемой в каждой части приложения.

Что может быть решением для контроля способа преобразования SoapClient xml в значения php? Было бы лучше разобрать xml-ответ самостоятельно? Может ли некоторая библиотека, подобная Zend \ Soap, помогать в этих случаях использования? Где я могу найти справочную документацию о том, как SoapClient преобразует xml в значения php?

ответ

0

Я настоятельно рекомендую использовать WSDL для php-генератора, поэтому вы всегда будете иметь объекты PHP того типа, который вы ожидаете, или массив, если вы должны получить массив. Вы должны попробовать проект PackageGenerator.

2

Решение состоит в том, чтобы включить функцию SOAP_SINGLE_ELEMENT_ARRAYS при создании SoapClient:

$client = new SoapClient($wsdl, array(
    'features' => SOAP_SINGLE_ELEMENT_ARRAYS, 
)); 
Смежные вопросы