Как мне перехватить данные из XML-содержимого SOAP-запроса на php SoapServer?

StackOverflow https://stackoverflow.com//questions/12692797

  •  12-12-2019
  •  | 
  •  

Вопрос

Я пытаюсь настроить SOAP-сервис на php.Я объявил серверную php-функцию, и я могу вызвать эту функцию с помощью http-запроса типа SOAP, где содержимым является мой SOAP-конверт.

XML-содержимое тела SOAP является аргументом функции, которую я предполагаю, но я не знаю, как получить доступ к содержащейся в нем информации в моем php-коде.

Я заметил, что аргумент функции является экземпляром stdClass по умолчанию, и я на самом деле удивляюсь, почему он не применяется к XML или DOM object by php - это вызов SOAP, не так ли?Но все в порядке, теперь мне нужно извлечь информацию из объекта, что непросто, потому что для этого нет назначенных методов stdClass, так что это должны быть стандартные функции php.Поэтому я попытался serialize, но это дало мне какой-то мусор, а не строку XML, которую я ожидал.

Что делать?

РЕДАКТИРОВАТЬ

обратите внимание, что ниже нет примера кода того, что я хочу сделать - получить некоторые подробные данные из содержимого XML запроса SOAP - потому что я не знаю, как закодировать получение этого из объекта stdClass

По просьбе Дэвида, вот некоторые подробности.

php-код:

<?php
    function mi102($arg) {
        $txt = serialize ($arg);
        $result = new SoapVar ($txt, XSD_ANYXML);
        return($result);
    }
    ini_set( "soap.wsdl_cache_enabled", "0");
    $server = new SoapServer ("test.wsdl");
    $server -> addFunction ("mi102");
    try {
        $server -> handle();
    }
    catch (Exception $e) {
        $server -> fault ('Client', $e -> getMessage());
    }
?php>

http-запрос создается приложением, которое я использую;http-заголовок и soap-конверт + тело генерируются на основе XML, который я ему передаю:

Содержимое тела запроса SOAP:

<mi102 xmlns="http://pse">
  <cdhead cisprik="21"/>
  <instr>
    <insid>
      <bcdt>20120930</bcdt>
    </insid>
  </instr>
</mi102>

Используемый WSDL выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://pse/" xmlns:xs="http://www.w3.org/2001/XMLSchema" name="PSE" targetNamespace="http://pse/">
    <types>
        <xs:schema>
            <xs:import namespace="http://pse/" schemaLocation="PSE.xsd"/>
        </xs:schema>
    </types>
    <message name="MI102Req">
        <part name="cdhead" type="tns:cdhead_T"/>
        <part name="instr" type="tns:instr_T"/>
    </message>
    <message name="Res">
        <part name="cdhead" type="tns:cdhead_T"/>
    </message>
    <portType name="MIPortType">
        <operation name="mi102">
            <input message="tns:MI102Req"/>
            <output message="tns:Res"/>
        </operation>
    </portType>
    <binding name="MIBinding" type="tns:MIPortType">
        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="mi102">
            <soap:operation soapAction="http://testServerURL/test_soap.php#mi102"/>
            <input>
                <soap:body use="literal" namespace="http://pse/"/>
            </input>
            <output>
                <soap:body use="literal" namespace="http://pse/"/>
            </output>
        </operation>
    </binding>
    <service name="PSE">
        <port name="MIPortType" binding="tns:MIBinding">
            <soap:address location="http://testServerURL/test_soap.php"/>
        </port>
    </service>
</definitions>

И результирующий XML (опять же, извлеченный из тела SOAP приложением, которое я использую), является

SOAP-ответ:

<?xml version="1.0" encoding="UTF-8"?>
<ns1:mi102Response xmlns:ns1="http://pse/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">O:8:"stdClass":2:{s:7:"cisprik";i:21;s:7:"version";s:2:"13";}</ns1:mi102Response>

Нехорошо.

Это было полезно?

Решение

В конце концов я нашел ответ в других темах на SO, например получить-полученный-xml-с-php-soap-сервера

Решение заключается в использовании следующего:

$inp = file_get_contents ('php://input');

Примечание:Я не смог найти ни одной функции, которая могла бы воздействовать на stdClass введите аргумент и можете извлечь из него содержимое тела XML SOAP.
Таким образом, лучший вариант - использовать стандартную входную переменную php.Обратите внимание, что это имеет следующую структуру: Envelope/Body/..inputXML.., который является точным содержимым http-запроса, отправляемого на сервер.

Примечание: http_get_request_body тоже может сработать, но мой php-сервер не поддерживал эту функцию.Я думаю, что file_get_contents поддерживается на каждом php-сервере, начиная с какой-либо версии и далее.

Другие советы

Это не начнется как полный ответ, но я хотел форматирование. Пожалуйста, уточните, что вы настроили. Как правило, у вас будет метод PHP с регулярными аргументами (не XML), который вы хотите выставить в качестве веб-службы. Основной пример о том, как это сделать здесь:

http://www.phpeverydayday. COM / Статьи / Веб-сервисы-WSDL-Создание-SOAP-SERVER-P484.HTML

Содержание XML в корпусе SOAP - это аргумент функции, которую я предполагаю

Нет, содержание XML в корпусе мыла - это представление метода с вашими аргументами, но ваши аргументы - это то, что вы хотите. Вам не нужно иметь дело с XML вручную, если вы настроете его с помощью SOAPSERVER и SOAPCLIARD.

Редактировать: Вы принимаете свой аргумент, что является простым представлением PHP-массива вашего тела SOAP, сериализующее его и отправляя его обратно в качестве ответа (который является то, что вы наблюдаете). Это то, что вы хотите сделать? Разве вы не хотите что-то сделать с данными запроса? Кроме того, вы можете опубликовать схему, которая импортируется из WSDL?

У вас есть что «не приятное» представление объекта, потому что вы возвращаете объект, сериализованный (сериализация преобразует объект и его состояние в строковое представление). Если вы хотите иметь представление XML возвращенного объекта, вы должны изменить тип возвращаемого параметра вашей функции на объект. Потому что сейчас возвращает строку.

Я бы порекомендовал вам использовать компоненты zend_soap_server и zend_soap_autoDoCover.

С ZEND_SOOP_AUTODISCOVOVER Вы можете создать определение вашего веб-сервиса (WSDL) динамически, просто написав Docblocks ваших функций. И zend_soap_server тоже довольно круто.

Если вы используете эти компоненты и документируете свои типы и вашу функцию, чтобы вернуть определенный тип без сериала, то вы собираетесь получать представление XML в соответствии с определением WSDL. Также каждый тип, который вы создаете автоматически конвертируются Zend_SOAP_AUTODOCOVOVER на CompartyType в создании WSDL.

Образец:

 public class Person{
         public $id;
         public $name;
    }

    public class MyService {
     /**
     *
     * @param integer $UserID
     * @return Person
     */
    function mi102($UserID) {

         $output = new Person();
         $output->id = 2;
         $output->name = 'Peter';        

        return $output;
    }
}


// Generate WSDL relevant to code
if (isset($_GET['wsdl'])){

    $autodiscover = new Zend_Soap_AutoDiscover();
    $autodiscover->setClass('MyService');
    $autodiscover->handle();

} else {

    $server = new Zend_Soap_Server($serviceURL . "?wsdl");
    $server->setClass('MyService');
    $server->setObject(new MyService());
    $server->handle();

}
.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top