Como faço para capturar dados do conteúdo XML de uma solicitação SOAP em um SOAPServer php?

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

  •  12-12-2019
  •  | 
  •  

Pergunta

Estou tentando configurar um serviço SOAP em php.Declarei uma função php de servidor e posso chamar essa função com uma solicitação http do tipo SOAP, onde o conteúdo é meu envelope SOAP.

O conteúdo XML do corpo SOAP é o argumento da função que assumo, mas não sei como acessar as informações contidas nele no meu código php.

Notei que o argumento da função é uma instância de stdClass por padrão, e eu realmente me pergunto por que não é lançado em um XML ou DOM object por php - é uma chamada SOAP, não é?Mas tudo bem, agora cabe a mim retirar as informações do objeto, o que não é fácil porque não há métodos atribuídos a ele. stdClass, então terão que ser funções php padrão.Então eu tentei serialize, mas isso me deu algum lixo, não a string XML que eu esperava.

O que fazer?

EDITAR

observe que abaixo não há código de exemplo do que desejo fazer - obter alguns dados detalhados do conteúdo XML da solicitação SOAP - porque não sei como codificar para obtê-los do objeto stdClass

A pedido de David, aqui estão alguns detalhes.

código 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>

a solicitação http é construída por um aplicativo que eu uso;o cabeçalho http e o envelope soap + corpo são gerados em torno do XML que eu alimento:

Conteúdo do corpo da solicitação SOAP:

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

O WSDL usado é o seguinte:

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

E o XML resultante (novamente, extraído do corpo SOAP pela aplicação que uso), é

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

Não é legal.

Foi útil?

Solução

Acabei encontrando a resposta em outros tópicos do SO, como obter-recebido-xml-do-php-soap-server

A solução é usar o seguinte:

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

Observação:Não consegui encontrar nenhuma função que possa atuar no stdClass argumento de entrada e pode recuperar o conteúdo do corpo XML SOAP dele.
Portanto, a melhor opção é usar a variável de entrada padrão do php.Observe que isso tem a seguinte estrutura: Envelope/Body/..inputXML.., que é o conteúdo exato da solicitação http postado no servidor.

Observação: http_get_request_body pode funcionar também, mas meu servidor php não suportava esta função.eu penso isso file_get_contents é suportado em todos os servidores php de alguma versão em diante.

Outras dicas

Isso não vai começar como uma resposta completa, mas eu queria a formatação.Explique o que você configurou.Geralmente, você terá um método PHP com argumentos regulares (não XML) que deseja expor como um serviço web.Um exemplo básico de como fazer isso está aqui:

http://www.phpeveryday.com/articles/Web-Services-WSDL-Creating-SOAP-Server-P484.html

O conteúdo XML do corpo SOAP é o argumento da função que presumo

Não, o conteúdo XML do corpo SOAP é o representação do método com seus argumentos, mas seus argumentos são o que você quiser.Você não deverá ter que lidar com XML manualmente se configurá-lo com SoapServer e SoapClient do PHP.

EDITAR:Você está pegando seu argumento, que é uma representação simples de array PHP do corpo da sua solicitação SOAP, serializando-o e enviando-o de volta como uma resposta (que é o que você observa).É isso que você quer fazer?Você não quer fazer algo com os dados da solicitação?Além disso, você pode postar o esquema importado do WSDL?

Você está tendo aquela representação "nada legal" de um objeto porque está retornando o objeto serializado (a serialização está convertendo o objeto e seu estado em uma representação de string).Se você deseja ter uma representação xml do objeto retornado, você deve alterar o tipo de parâmetro de retorno da sua função para um objeto.Porque agora está retornando uma string.

Eu recomendo que você use os componentes Zend_Soap_Server e Zend_Soap_Autodiscover do framework zend.

Com Zend_Soap_Autodiscover você pode gerar sua definição de serviço web (wsdl) dinamicamente, apenas escrevendo os docblocks de suas funções.E Zend_Soap_Server também é muito legal.

Se você usar esses componentes e documentar seus tipos e sua função para retornar um tipo específico sem serializá-lo, você receberá a representação xml de acordo com a definição WSDL.Além disso, cada tipo criado é convertido automaticamente pelo Zend_Soap_Autodiscover em um ComplexType no wsdl gerado.

Amostra:

 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();

}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top