Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Rodrigo Yoshida

[Resolvido] Problema com tipos complexos em web service

Recommended Posts

Opa.

 

Estou criando um servidor web service utilizando o SOAP nativo no PHP 5, porém estou tendo problemas com tipos complexos.

A princípio estou utilizando a classe SoapParam para criá-los, da seguinte maneira:

 

 

$perfil = array(

'Nome' => 'Rodrigo Y. M. Y.',

'Email' => 'rodrigo@rodrigo.com',

'Idade' => 25

)

);

 

return new SoapParam($perfil, 'Perfil');

 

 

Eu recebo um XML da seguinte maneira, que está correto pelo que estou fazendo:

 

<Email xsi:type="xsd:string">rodrigoyoshida@live.com</Email>

<Idade xsi:type="xsd:int">25</Idade>

<Nome xsi:type="xsd:string">Rodrigo Yoshida</Nome>

 

 

Porém eu preciso fazer ele gerar um XML mais complexo, com outros níveis (filhos), o resultado que estou esperando é algo do tipo:

 

<Email xsi:type="xsd:string">rodrigoyoshida@live.com</Email>

<Idade xsi:type="xsd:int">25</Idade>

<Nome xsi:type="xsd:string">Rodrigo Yoshida</Nome>

<Atributos>

<Altura xsi:type="xsd:int">1.75</Altura>

<Pele xsi:type="xsd:int">Branco</Pele>

</atributos>

 

 

Pesquisei na documentação do Soap, estou há horas pesquisando no Google mas nada, pelo que vejo o suporte do Soap nativo é bem fraco, pois não vi essa dúvida em lugar algum, ou de repente estou procurando da maneira errada.

 

Alguém tem idéia de como posso fazer isso?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Rodrigo,

 

Tente esquecer o SoapParam, tente fazer assim:

 

$request = new stdClass();
$request->Email = 'rodrigoyoshida@live.com';
$request->Idade = 25;
$request->Nome = 'Rodrigo Yoshida';
$request->Atributos = new stdClass();
$request->Atributos->Altura = 1.75; //isso aqui é um float e não um int, veja seu WSDL qual o tipo definido
$request->Atributos->Pele = 'Branco';

$soapClient->seuMetodo( $request ); //Passe direto o stdClass, SoapClient fará o resto para você

Compartilhar este post


Link para o post
Compartilhar em outros sites

Opa, no exemplo foi utilizado enviando do cliente para um método no servidor, eu poderia utilizar isso como resposta para um cliente também?

 

 

Rodrigo,

 

Tente esquecer o SoapParam, tente fazer assim:

 

$request = new stdClass();
$request->Email = 'rodrigoyoshida@live.com';
$request->Idade = 25;
$request->Nome = 'Rodrigo Yoshida';
$request->Atributos = new stdClass();
$request->Atributos->Altura = 1.75; //isso aqui é um float e não um int, veja seu WSDL qual o tipo definido
$request->Atributos->Pele = 'Branco';

$soapClient->seuMetodo( $request ); //Passe direto o stdClass, SoapClient fará o resto para você

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Claro Rodrigo, sem problemas.

 

Poste seu WSDL ou um link para ele, fica mais fácil para ajudá-lo, talvez até com um exemplo mais prático.

 

;)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Opa, então, poxa, não sei como agradecer! Eu estou procurando aqui desde ontem e não consegui achar nada. A princípio funcionou! Porém não sei porque o "segundo nível" não apareceu no XML, talvez o WSDL esteja errado mesmo, aproveitando, gostaria de fazer outras duas perguntas. Você recomenda algum gerador de WSDL ou é melhor fazer na mão? A segunda pergunta é, onde eu encontro um BOM material sobre web services em php? Tudo que acho é muito superficial.

 

 

 

Segue abaixo o WSDL, o código PHP e o retorno em XML que estou recebendo:

 

WSDL:

 

This XML file does not appear to have any style information associated with it. The document tree is shown below.

 

<wsdl:definitions targetNamespace="http://schema.example.com">

<wsdl:types>

<xsd:schema targetNamespace="http://schema.example.com">

<xsd:complexType name="Perfil">

<xsd:all>

<xsd:element name="Email" type="xsd:string"/>

<xsd:element name="Idade" type="xsd:int"/>

<xsd:element name="Nome" type="xsd:string"/>

</xsd:all>

</xsd:complexType>

<xsd:complexType name="Atributos">

<xsd:all>

<xsd:element name="Altura" type="xsd:string"/>

<xsd:element name="Peso" type="xsd:int"/>

</xsd:all>

</xsd:complexType>

</xsd:schema>

</wsdl:types>

<message name="retornaDadosRequest"/>

<message name="retornaDadosResponse">

<part name="retornaDadosReturn" type="tns:Perfil"/>

</message>

<message name="retornaDados2Request"/>

<message name="retornaDados2Response">

<part name="retornaDados2Return" type="tns:Atributos"/>

</message>

<wsdl:portType name="testeWSPortType">

<wsdl:operation name="retornaDados">

<wsdl:input message="tns:retornaDadosRequest"/>

<wsdl:output message="tns:retornaDadosResponse"/>

</wsdl:operation>

<wsdl:operation name="retornaDados2">

<wsdl:input message="tns:retornaDados2Request"/>

<wsdl:output message="tns:retornaDados2Response"/>

</wsdl:operation>

</wsdl:portType>

<binding name="testeWSBinding" type="tns:testeWSPortType">

<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>

<wsdl:operation name="retornaDados">

<soap:operation soapAction="http://localhost:8888/_ws/service.php?class=testeWS&method=retornaDados" style="rpc"/>

<wsdl:input>

<soap:body use="encoded" namespace="http://schema.example.com" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>

</wsdl:input>

<wsdl:output>

<soap:body use="encoded" namespace="http://schema.example.com" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>

</wsdl:output>

</wsdl:operation>

<wsdl:operation name="retornaDados2">

<soap:operation soapAction="http://localhost:8888/_ws/service.php?class=testeWS&method=retornaDados2" style="rpc"/>

<wsdl:input>

<soap:body use="encoded" namespace="http://schema.example.com" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>

</wsdl:input>

<wsdl:output>

<soap:body use="encoded" namespace="http://schema.example.com" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>

</wsdl:output>

</wsdl:operation>

</binding>

<wsdl:service name="testeWS">

<wsdl:port name="testeWSPort" binding="tns:testeWSBinding">

<soap:address location="http://localhost:8888/_ws/service.php?class=testeWS"/>

</wsdl:port>

</wsdl:service>

</wsdl:definitions>

 

 

 

Código PHP:

 

$perfil = new stdClass();

$perfil->Nome = 'Rodrigo Yoshida';

$perfil->Email = 'rodrigo@yoshida.com';

$perfil->Idade = 25;

$perfil->Atributos = new stdClass();

$perfil->Atributos->Altura = '1.75';

$perfil->Atributos->Peso = 50;

 

 

return $perfil;

 

 

 

Retorno em XML:

<SOAP-ENV:Envelope

xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:xsd="http://www.w3.org/2001/XMLSchema"

xmlns:ns1="http://schema.example.com"

xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"

>

<SOAP-ENV:Body>

<ns1:retornaDadosResponse xmlns:ns1="http://schema.example.com">

<retornaDadosReturn xsi:type="ns1:Perfil">

<Email xsi:type="xsd:string">rodrigo@yoshida.com</Email>

<Idade xsi:type="xsd:int">25</Idade>

<Nome xsi:type="xsd:string">Rodrigo Yoshida</Nome>

</retornaDadosReturn>

</ns1:retornaDadosResponse>

</SOAP-ENV:Body>

</SOAP-ENV:Envelope>

 

 

 

 

 

 

 

 

 

 

Claro Rodrigo, sem problemas.

 

Poste seu WSDL ou um link para ele, fica mais fácil para ajudá-lo, talvez até com um exemplo mais prático.

 

;)

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Você recomenda algum gerador de WSDL ou é melhor fazer na mão?

 

Eu, pessoalmente, gosto de escrever meu WSDL no braço, mas é uma questão pessoal minha, se você preferir, dê uma olhada no NuSOAP, ele fará muito, do trabalho complexo do servidor para você.

 

A segunda pergunta é, onde eu encontro um BOM material sobre web services em php? Tudo que acho é muito superficial.

 

Bom, eu não sei lhe dizer, eu estudei pela especificação da W3C, talvez seja por isso que eu gosto de fazer no braço...

 

Mas não deixe de perguntar caso tenha dúvidas, tentaremos ajudá-lo.

 

Segue abaixo o WSDL, o código PHP e o retorno em XML que estou recebendo:

 

Certo, você copiou a saída do navegador, em vez disso, mande exibir o código fonte e copie o código de lá, pelo navegador ficam faltando informações de namespace.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Opa, estive fazendo com o Soap nativo do PHP e um "gerador" de WSDL chamado "WSDL helper", ele já gera uma documentação básica também. Vou dar uma pesquisada sobre o NuSoap, não considerei utilizar ele pois não é nativo, então acabei deixando de lado. Tem algum material dele pra recomendar?

 

Sobre o WSDL, então, vou colar aqui, porém ele está sem tabulação nenhuma, pois o gerador coloca tudo numa linha só, aí vai:

 

<?xml version="1.0"?>
<wsdl:definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://schema.example.com"
targetNamespace="http://schema.example.com">

<wsdl:types>
	<xsd:schema targetNamespace="http://schema.example.com">
		<xsd:complexType name="Perfil">
			<xsd:all>
				<xsd:element name="Email" type="xsd:string" />
				<xsd:element name="Idade" type="xsd:int" />
				<xsd:element name="Nome" type="xsd:string" />
			</xsd:all>
		</xsd:complexType>
		<xsd:complexType name="Atributos">
			<xsd:all>
				<xsd:element name="Altura" type="xsd:string" />
				<xsd:element name="Peso" type="xsd:int" />
			</xsd:all>
		</xsd:complexType>
	</xsd:schema>
</wsdl:types>
<message name="retornaDadosRequest" />
<message name="retornaDadosResponse">
	<part name="retornaDadosReturn" type="tns:Perfil" />
</message>
<message name="retornaDados2Request" />
<message name="retornaDados2Response">
	<part name="retornaDados2Return" type="tns:Atributos" />
</message>
<wsdl:portType name="testeWSPortType">
	<wsdl:operation name="retornaDados">
		<wsdl:input message="tns:retornaDadosRequest" />
		<wsdl:output message="tns:retornaDadosResponse" />
	</wsdl:operation>
	<wsdl:operation name="retornaDados2">
		<wsdl:input message="tns:retornaDados2Request" />
		<wsdl:output message="tns:retornaDados2Response" />
	</wsdl:operation>
</wsdl:portType>
<binding name="testeWSBinding" type="tns:testeWSPortType">
	<soap:binding style="rpc"
		transport="http://schemas.xmlsoap.org/soap/http" />
	<wsdl:operation name="retornaDados">
		<soap:operation
			soapAction="http://localhost:8888/_ws/service.php?class=testeWS&method=retornaDados"
			style="rpc" />
		<wsdl:input>
			<soap:body use="encoded" namespace="http://schema.example.com"
				encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
		</wsdl:input>
		<wsdl:output>
			<soap:body use="encoded" namespace="http://schema.example.com"
				encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
		</wsdl:output>
	</wsdl:operation>
	<wsdl:operation name="retornaDados2">
		<soap:operation
			soapAction="http://localhost:8888/_ws/service.php?class=testeWS&method=retornaDados2"
			style="rpc" />
		<wsdl:input>
			<soap:body use="encoded" namespace="http://schema.example.com"
				encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
		</wsdl:input>
		<wsdl:output>
			<soap:body use="encoded" namespace="http://schema.example.com"
				encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
		</wsdl:output>
	</wsdl:operation>
</binding>
<wsdl:service name="testeWS">
	<wsdl:port name="testeWSPort" binding="tns:testeWSBinding">
		<soap:address location="http://localhost:8888/_ws/service.php?class=testeWS" />
	</wsdl:port>
</wsdl:service>
</wsdl:definitions>

Compartilhar este post


Link para o post
Compartilhar em outros sites

Certo, Rodrigo:

 

<message name="retornaDadosResponse">
<part name="retornaDadosReturn" type="tns:Perfil" />
</message>

 

Perceba que seu retorno é um tns:Perfil, agora, veja só:

 

<xsd:complexType name="Perfil">
<xsd:all>
	<xsd:element name="Email" type="xsd:string" />
	<xsd:element name="Idade" type="xsd:int" />
	<xsd:element name="Nome" type="xsd:string" />
</xsd:all>
</xsd:complexType>

 

O tipo Perfil não possui um elemento Atributos...

 

Seu WSDL deveria ficar assim:

<?xml version="1.0"?>
<wsdl:definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://schema.example.com" targetNamespace="http://schema.example.com">

<wsdl:types>
	<xsd:schema targetNamespace="http://schema.example.com">
		<xsd:complexType name="Perfil">
			<xsd:all>
				<xsd:element name="Email" type="xsd:string" />
				<xsd:element name="Idade" type="xsd:int" />
				<xsd:element name="Nome" type="xsd:string" />
				<!--
				Veja que agora possuímos o elemento Atributos 
				-->
				<xsd:element name="Atributos" type="tns:Atributos" />
			</xsd:all>
		</xsd:complexType>
		<xsd:complexType name="Atributos">
			<xsd:all>
				<xsd:element name="Altura" type="xsd:string" />
				<xsd:element name="Peso" type="xsd:int" />
			</xsd:all>
		</xsd:complexType>
	</xsd:schema>
</wsdl:types>
<message name="retornaDadosRequest" />
<message name="retornaDadosResponse">
	<part name="retornaDadosReturn" type="tns:Perfil" />
</message>
<message name="retornaDados2Request" />
<message name="retornaDados2Response">
	<part name="retornaDados2Return" type="tns:Atributos" />
</message>
<wsdl:portType name="testeWSPortType">
	<wsdl:operation name="retornaDados">
		<wsdl:input message="tns:retornaDadosRequest" />
		<wsdl:output message="tns:retornaDadosResponse" />
	</wsdl:operation>
	<wsdl:operation name="retornaDados2">
		<wsdl:input message="tns:retornaDados2Request" />
		<wsdl:output message="tns:retornaDados2Response" />
	</wsdl:operation>
</wsdl:portType>
<binding name="testeWSBinding" type="tns:testeWSPortType">
	<soap:binding style="rpc"
		transport="http://schemas.xmlsoap.org/soap/http" />
	<wsdl:operation name="retornaDados">
		<soap:operation
			soapAction="http://localhost:8888/_ws/service.php?class=testeWS&method=retornaDados"
			style="rpc" />
		<wsdl:input>
			<soap:body use="encoded" namespace="http://schema.example.com"
				encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
		</wsdl:input>
		<wsdl:output>
			<soap:body use="encoded" namespace="http://schema.example.com"
				encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
		</wsdl:output>
	</wsdl:operation>
	<wsdl:operation name="retornaDados2">
		<soap:operation
			soapAction="http://localhost:8888/_ws/service.php?class=testeWS&method=retornaDados2"
			style="rpc" />
		<wsdl:input>
			<soap:body use="encoded" namespace="http://schema.example.com"
				encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
		</wsdl:input>
		<wsdl:output>
			<soap:body use="encoded" namespace="http://schema.example.com"
				encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
		</wsdl:output>
	</wsdl:operation>
</binding>
<wsdl:service name="testeWS">
	<wsdl:port name="testeWSPort" binding="tns:testeWSBinding">
		<soap:address location="http://localhost:8888/_ws/service.php?class=testeWS" />
	</wsdl:port>
</wsdl:service>
</wsdl:definitions>

 

Dessa forma, o fragmento PHP passado anteriormente funcionará para o retorno.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cara, eu realmente não sei mesmo como agradecer a ajuda! Pesquisei durante horas mas não consegui achar nada falando sobre isso, aliás, material sobre web services em PHP me parece meio escasso, tudo que vi era muito básico, ensinando como retornar apenas strings, int ou no máximo com tipos complexos com o SoapParam como estava tentando da primeira vez.

 

Pra finalizar, sobre este WSDL que colei no tópico, ele está correto? Utilizei um script de terceiros para gerar ele, o cliente Soap que tenho instalado aqui na máquina leu ele sem problemas, mas de repente pode ter algo errado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pra finalizar, sobre este WSDL que colei no tópico, ele está correto?

 

Bom, correto, amigo, é relativo. Se está funcionando ai, está correto. :D

 

Eu, contudo, o faria um pouco diferente, você utilizou RPC encoded, eu utilizaria DOCUMENT literal. Se eu estivesse escrevendo esse WSDL, ele ficaria assim:

 

 

<?xml version="1.0"?>
<wsdl:definitions
name="service"
xmlns:tns="urn:Rodrigo/service/"
xmlns:soap="http-~~-//schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http-~~-//schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http-~~-//www.w3.org/2001/XMLSchema"
targetNamespace="urn:Rodrigo/service/">

<wsdl:types>
	<xsd:schema targetNamespace="urn:Rodrigo/service/">
		<xsd:element name="perfil" type="tns:Perfil" />
		<xsd:element name="atributos" type="tns:Atributos" />

		<xsd:complexType name="Perfil">
			<xsd:sequence>
				<xsd:element name="Email" type="xsd:string" />
				<xsd:element name="Idade" type="xsd:int" />
				<xsd:element name="Nome" type="xsd:string" />
				<xsd:element name="Atributos" type="tns:Atributos" />
			</xsd:sequence>
		</xsd:complexType>

		<xsd:complexType name="Atributos">
			<xsd:all>
				<xsd:element name="Altura" type="xsd:string" />
				<xsd:element name="Peso" type="xsd:int" />
			</xsd:all>
		</xsd:complexType>
	</xsd:schema>
</wsdl:types>

<wsdl:message name="retornaDadosRequest" />
<wsdl:message name="retornaDadosResponse">
	<wsdl:part element="tns:perfil" name="response"/>
</wsdl:message>

<wsdl:message name="retornaDados2Request" />
<wsdl:message name="retornaDados2Response">
	<wsdl:part element="tns:atributos" name="response"/>
</wsdl:message>

<wsdl:portType name="testeWSPortType">
	<wsdl:operation name="retornaDados">
		<wsdl:input message="tns:retornaDadosRequest" />
		<wsdl:output message="tns:retornaDadosResponse" />
	</wsdl:operation>
	<wsdl:operation name="retornaDados2">
		<wsdl:input message="tns:retornaDados2Request" />
		<wsdl:output message="tns:retornaDados2Response" />
	</wsdl:operation>
</wsdl:portType>

<wsdl:binding name="testeWSBinding" type="tns:testeWSPortType">
	<soap:binding style="document" transport="http-~~-//schemas.xmlsoap.org/soap/http" />

	<wsdl:operation name="retornaDados">
		<soap:operation soapAction="urn:Rodrigo/service/retornaDados/" />
		<wsdl:input>
			<soap:body use="literal" />
		</wsdl:input>
		<wsdl:output>
			<soap:body use="literal" />
		</wsdl:output>
	</wsdl:operation>

	<wsdl:operation name="retornaDados2">
		<soap:operation soapAction="urn:Rodrigo/service/retornaDados2/" />
		<wsdl:input>
			<soap:body use="literal" />
		</wsdl:input>
		<wsdl:output>
			<soap:body use="literal" />
		</wsdl:output>
	</wsdl:operation>
</wsdl:binding>

<wsdl:service name="testeWS">
	<wsdl:port name="testeWSPort" binding="tns:testeWSBinding">
		<soap:address location="http-~~-//localhost:8888/_ws/service.php?class=testeWS" />
	</wsdl:port>
</wsdl:service>
</wsdl:definitions>

 

 

 

1. Veja que todos os elementos são qualificados

2. Veja que agora, temos 2 elementos em wsdl:types: perfil e atributos (cujo tipos são definidos pelos respectivos xsd:complexType)

3. Veja que wsdl:message referencia um elemento de wsdl:types e não um xsd:complexType

4. Veja que wsdl:binding agora é document literal com transporte via HTTP

 

Você deve estar se perguntando: "Se funciona da outra forma, qual a diferença ?"

 

Por experiência (trabalho com webservices praticamente em todos meus projetos), percebi que cada ferramenta implementa SOAP de uma forma distinta e, nem todas, implementam por completo. Depois de ter vários problemas com clientes cujas ferramentas, feitas em Delphi, Genexus e outras, percebi que, seguindo todas as recomendações e especificações, a margem de problemas relacionados com incompatibilidade diminuem drasticamente, chegando a 0, se todas as recomendações forem seguidas.

 

Por isso, recomendo a leitura, na ordem que aparecem, de:

 

1. W3C SOAP http://forum.imasters.com.br/public/style_emoticons/default/seta.gif http://www.w3.org/TR/soap/

2. W3C XML Schema http://forum.imasters.com.br/public/style_emoticons/default/seta.gif http://www.w3.org/XML/Schema (Ênfase para Specifications and Development)

3. W3C WSDL http://forum.imasters.com.br/public/style_emoticons/default/seta.gif http://www.w3.org/TR/wsdl

4. WS-I http://forum.imasters.com.br/public/style_emoticons/default/seta.gif http://www.ws-i.org/

 

Outros recursos para leitura:

 

W3Schools SOAP http://forum.imasters.com.br/public/style_emoticons/default/seta.gif http://www.w3schools...oap/default.asp

W3Schools XML Schema http://forum.imasters.com.br/public/style_emoticons/default/seta.gif http://www.w3schools...ema/default.asp

W3Schools WSDL http://forum.imasters.com.br/public/style_emoticons/default/seta.gif http://www.w3schools...sdl/default.asp

Compartilhar este post


Link para o post
Compartilhar em outros sites

Opa, já coloquei na lista para começar a estudar por esses links! Terminando o trabalho aqui apareceu uma última dúvida. Qual seria a diferença entre as duas maneiras de se passar atributos para um método em um servidor web service entre as duas abaixo? Existe uma certa ou mais indicada? Até porque dependendo da abordagem deles o método no servidor mudaria para receber os dados.

 

 

Maneira 1:

$wsClient = new SoapClient("http://localhost/meuWebService.php?wsdl");
$resposta = $wsClient->verProduto(12, 23);

 

 

Maneira 2:

$variaveis = new stdClass();
$variaveis->Codigo = 12;
$variaveis->Categoria = 23;

$wsClient = new SoapClient("http://localhost/meuWebService.php?wsdl");
$resposta = $wsClient->verProduto($variaveis);

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom, vou tentar explicar da melhor maneira como o servidor web service precisa funcionar, pra informação não ficar fragmentada no tópico.

 

Hoje preciso fazer um servidor web service que vai ser acessado por um ERP, ele precisa sincronizar os produtos cadastrados no ERP e exibi-los no site. É necessário apenas um método que irá receber dois parâmetros e o método irá retornar um array com uma lista de produtos. Vou tentar exemplificar em XML o que será enviado e o que ele teria que retornar.

 

 

XML enviado:

<Produtos>
<CodigoFilial>2</CodigoFilial>
<CodProduto>3244</CodProduto>
<Produtos>

 

 

XML recebido:

<Produtos>
<Item>
<Nome>Notebook HP</Nome>
<Valor>2550,00</Valor>
<Caracteristicas>
<Peso>1.2</Peso>
<Altura>15cm</Altura>
</Caracteristicas>
</item>
<Produtos>

 

 

 

Até aí digamos que eu consiga fazer, principalmente depois da ajuda daqui do fórum, porém existe uma segunda situação onde ele teria que retornar uma resposta diferente, aí eu não estaria conseguindo fazer, que seria a seguinte: O XML enviado teria o valor 'CodProduto' vazio, ou seja, estaria indicando para o método no servidor que o cliente quer a lista completa dos produtos daquele servidor, logo a resposta teria que ser algo tipo:

 

XML recebido:

<Produtos>
<Item>
<Nome>Notebook HP</Nome>
<Valor>2550,00</Valor>
<Caracteristicas>
<Peso>1.2</Peso>
<Altura>15cm</Altura>
</Caracteristicas>
</item>

<Item>
<Nome>iMac 21.5</Nome>
<Valor>3900,00</Valor>
<Caracteristicas>
<Peso>4</Peso>
<Altura>60cm</Altura>
</Caracteristicas>
</item>

<Item>
<Nome>Mouse</Nome>
<Valor>29,00</Valor>
<Caracteristicas>
<Peso>0.2</Peso>
<Altura>5cm</Altura>
</Caracteristicas>
</item>
<Produtos>

 

 

Talvez possa parecer estranho o fato de existir o pai "Características" com os filhos "Peso" e "Altura" sendo que poderia jogá-los como filhos do "Item", porém isto será necessário pois na verdade existem bem mais campos para serem recebidos, logo eu precisaria desse modo de organizar.

 

Pelo que li a respeito está relacionado a algo com "ArrayOf", pesquisando no Google achei material a respeito dele, mas não consegui fazer nenhum exemplo funcionar. A idéia é repetir uma mesma tag que seria a "Item", ou seja, enviar um array, pois acredito que não teria problemas em enviar apenas um item, principalmente depois da ajuda aqui no tópico, porém não estou conseguindo enviar vários itens.

 

 

Para chamar o método estou usando:

$dados = new stdClass();
$dados->CodigoFilial = 2;
$dados->CodProduto = 3244;

$cliente->ListarProdutos($dados);

 

 

Para retornar tinha pensado em algo parecido com o exemplo abaixo (que não funcionou)

$retorno = new stdClass();
$retorno->Item[0] = new stdClass();
$retorno->Item[0]->$Nome = "Notebook HP";
$retorno->Item[0]->$Valor = "2550,00";
$retorno->Item[0]->$Caracteristicas = new stdClass();
$retorno->Item[0]->$Caracteristicas->$Peso = 1.2;
$retorno->Item[0]->$Caracteristicas->$Altura = "15cm";

$retorno->Item[1] = new stdClass();
$retorno->Item[1]->$Nome = "iMac 21.5";
$retorno->Item[1]->$Valor = "3900,00";
$retorno->Item[1]->$Caracteristicas = new stdClass();
$retorno->Item[1]->$Caracteristicas->$Peso = 4.0;
$retorno->Item[1]->$Caracteristicas->$Altura = "60cm";

return $retorno;

 

 

No WSDL realmente não faço a mínima idéia de como dizer que o Item é um array, imagino que tenha algo a ver com o "ArrayOf".

 

Agradeço pela ajuda de todos que tentarem me ajudar! http://forum.imasters.com.br/public/style_emoticons/default/joia.gif

Compartilhar este post


Link para o post
Compartilhar em outros sites

A idéia é repetir uma mesma tag que seria a "Item", ou seja, enviar um array,...porém não estou conseguindo enviar vários itens.

No WSDL realmente não faço a mínima idéia de como dizer que o Item é um array,

 

Bom, Rodrigo.

 

Quando eu disse para você estudar XML Schema antes de WSDL, foi justamente prevendo essa dúvida.

 

Então, pelo que eu entendi, você tem uma tabela de Filiais:

 mysql> SELECT * FROM `Filial`;
 +----------+------------+
 | idFilial | filialName |
 +----------+------------+
 | 	1 | Teste 	|
 +----------+------------+
 1 row in set (0.00 sec)

E tem uma tabela de produtos:

 mysql> SELECT * FROM `Product`;
 +-----------+----------+-------------+--------------+---------------+---------------+
 | idProduct | idFilial | productName | productValue | productHeight | productWeight |
 +-----------+----------+-------------+--------------+---------------+---------------+
 | 	1 | 	1 | Notebook HP | 	2550.00 | 	15.00 | 	1.20 |
 | 	2 | 	1 | iMac 21.5 | 	3900.00 | 	60.00 | 	4.00 |
 | 	3 | 	1 | Mouse 	| 	29.00 | 	5.00 | 	0.20 |
 +-----------+----------+-------------+--------------+---------------+---------------+
 3 rows in set (0.00 sec)

Você precisa que seu WS possa recuperar essas informações. Eu teria dois métodos:

 

WS.getProductByID( id );

WS.getProductsByFilial( filial );

 

Como, independentemente da forma que os dados virão, estamos falando de produtos, então, vamos definir um produto como tipo:

 

<!--
Aqui, definimos a base do produto:
productName: 	É definido como uma string e pode ocorrer no mínimo 1 e no máximo
	1 vez, ou seja, é requerido.
productValue: 	É definido como um float e, assim como o productName, é requerido.
productCharacteristic:	A característica do produto é definida como um tipo separado
-->
<xsd:complexType name="ProductType">
	<xsd:sequence>
		<xsd:element name="productName" type="xsd:string" minOccurs="1" maxOccurs="1" />
		<xsd:element name="productValue" type="xsd:float" minOccurs="1" maxOccurs="1" />
		<xsd:element name="productCharacteristic" type="tns:ProductCharacteristicType" minOccurs="1" maxOccurs="1" />
	</xsd:sequence>
</xsd:complexType>

<!--
Aqui, definimos apenas as características do produto:
productHeight: 	É um float e é requerido
productWeight: 	É um float e também é requerido 
-->
<xsd:complexType name="ProductCharacteristicType">
	<xsd:sequence>
		<xsd:element name="productHeight" type="xsd:float" minOccurs="1" maxOccurs="1" />
		<xsd:element name="productWeight" type="xsd:float" minOccurs="1" maxOccurs="1" />
	</xsd:sequence>
</xsd:complexType>

 

Até aqui, acredito que esteja tranquilo, veja apenas o detalhe do minOccurs e maxOccurs, eles são a resposta à sua dúvida sobre arrays.

 

Bom, então, teremos duas operações, a primeira que definiremos será WS.getProductByID( id ):

 

Essa requisição terá dois elementos:

<!--
Elemento associado com a requisição de um produto pelo ID
-->
<xsd:element name="idProduct" type="xsd:integer" />

<!--
Elemento associado com a resposta de uma requisição de produto pelo ID
-->
<xsd:element name="getProductByIDResponse" type="tns:ProductType" />

 

E nossas mensagens:

<!--
Requisição e resposta da operação getProductByID
requisição: tns:idProduct
resposta: tns:getProductByIDResponse
-->
<wsdl:message name="getProductByIDRequest">
	<wsdl:part element="tns:idProduct" name="idProduct"/>
</wsdl:message>
<wsdl:message name="getProductByIDResponse">
	<wsdl:part element="tns:getProductByIDResponse" name="response"/>
</wsdl:message>

 

Bom, até agora, só lidamos com um único produto, vamos ver como ficaria a requisição por filial, que também terá dois elementos:

<!--
Elemento associado com a requisição de produtos por Filial
-->
<xsd:element name="idFilial" type="xsd:integer" />

<!--
Elemento associado com a resposta de uma requisição de produto por Filial
-->
<xsd:element name="getProductsByFilialResponse" type="tns:ProductListType" />

 

Veja que a resposta é do tipo tns:ProductListType, definida assim:

<!--
Aqui, definimos uma lista de produtos, ao contrário dos outros tipos, a lista
poderá retornar um número indefinido produtos, inclusive 0.
Cada elemento da lista chamará item e será do tipo tns:ProductType, definido
anteriormente.
-->
<xsd:complexType name="ProductListType">
	<xsd:sequence>
		<xsd:element name="items" type="tns:ProductType" minOccurs="0" maxOccurs="unbounded" />
	</xsd:sequence>
</xsd:complexType>

 

Percebe que agora nossos atributos minOccurs e maxOccurs recebem valores um pouco diferentes dos demais, isso permitirá que trabalhemos com matrizes. Agora, da mesma forma das anterios, as mensagens ficam:

<!--
Requisição e resposta da operação getProductsByFilial
requisição: tns:idFilial
resposta: tns:getProductsByFilialResponse
-->
<wsdl:message name="getProductsByFilialRequest">
	<wsdl:part element="tns:idFilial" name="idFilial"/>
</wsdl:message>
<wsdl:message name="getProductsByFilialResponse">
	<wsdl:part element="tns:getProductsByFilialResponse" name="response"/>
</wsdl:message>

 

Com os tipos definidos, o WSDL ficaria assim:

 

 

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
	name="service"
	xmlns:tns="urn:Rodrigo/service/"
	xmlns:soap="http-~~-//schemas.xmlsoap.org/wsdl/soap/"
	xmlns:wsdl="http-~~-//schemas.xmlsoap.org/wsdl/"
	xmlns:xsd="http-~~-//www.w3.org/2001/XMLSchema"
	targetNamespace="urn:Rodrigo/service/">

	<wsdl:types>
		<xsd:schema targetNamespace="urn:Rodrigo/service/">
			<!--
			Elemento associado com a requisição de um produto pelo ID
			-->
			<xsd:element name="idProduct" type="xsd:integer" />

			<!--
			Elemento associado com a resposta de uma requisição de produto pelo ID
			-->
			<xsd:element name="getProductByIDResponse" type="tns:ProductType" />

			<!--
			Elemento associado com a requisição de produtos por Filial 
			-->
			<xsd:element name="idFilial" type="xsd:integer" />

			<!--
			Elemento associado com a resposta de uma requisição de produto por Filial
			-->
			<xsd:element name="getProductsByFilialResponse" type="tns:ProductListType" />

			<!--
			Aqui, definimos a base do produto:
			productName:			É definido como uma string e pode ocorrer no mínimo 1 e no máximo
									1 vez, ou seja, é requerido.
			productValue:			É definido como um float e, assim como o productName, é requerido.
			productCharacteristic:	A característica do produto é definida como um tipo separado
			-->
			<xsd:complexType name="ProductType">
				<xsd:sequence>
					<xsd:element name="productName" type="xsd:string" minOccurs="1" maxOccurs="1" />
					<xsd:element name="productValue" type="xsd:float" minOccurs="1" maxOccurs="1" />
					<xsd:element name="productCharacteristic" type="tns:ProductCharacteristicType" minOccurs="1" maxOccurs="1" />
				</xsd:sequence>
			</xsd:complexType>

			<!--
			Aqui, definimos apenas as características do produto:
			productHeight:			É um float e é requerido
			productWeight:			É um float e também é requerido 
			-->
			<xsd:complexType name="ProductCharacteristicType">
				<xsd:sequence>
					<xsd:element name="productHeight" type="xsd:float" minOccurs="1" maxOccurs="1" />
					<xsd:element name="productWeight" type="xsd:float" minOccurs="1" maxOccurs="1" />
				</xsd:sequence>
			</xsd:complexType>

			<!--
			Aqui, definimos uma lista de produtos, ao contrário dos outros tipos, a lista
			poderá retornar um número indefinido produtos, inclusive 0.
			Cada elemento da lista chamará item e será do tipo tns:ProductType, definido
			anteriormente.
			-->
			<xsd:complexType name="ProductListType">
				<xsd:sequence>
					<xsd:element name="items" type="tns:ProductType" minOccurs="0" maxOccurs="unbounded" />
				</xsd:sequence>
			</xsd:complexType>
		</xsd:schema>
	</wsdl:types>

	<!--
	Requisição e resposta da operação getProductByID
	requisição: tns:idProduct
	resposta: tns:getProductByIDResponse
	-->
	<wsdl:message name="getProductByIDRequest">
		<wsdl:part element="tns:idProduct" name="idProduct"/>
	</wsdl:message>
	<wsdl:message name="getProductByIDResponse">
		<wsdl:part element="tns:getProductByIDResponse" name="response"/>
	</wsdl:message>

	<!--
	Requisição e resposta da operação getProductsByFilial
	requisição: tns:idFilial
	resposta: tns:getProductsByFilialResponse
	-->
	<wsdl:message name="getProductsByFilialRequest">
		<wsdl:part element="tns:idFilial" name="idFilial"/>
	</wsdl:message>
	<wsdl:message name="getProductsByFilialResponse">
		<wsdl:part element="tns:getProductsByFilialResponse" name="response"/>
	</wsdl:message>

	<wsdl:portType name="service">
		<wsdl:operation name="getProductByID">
			<wsdl:input message="tns:getProductByIDRequest"/>
			<wsdl:output message="tns:getProductByIDResponse"/>
		</wsdl:operation>

		<wsdl:operation name="getProductsByFilial">
			<wsdl:input message="tns:getProductsByFilialRequest"/>
			<wsdl:output message="tns:getProductsByFilialResponse"/>
		</wsdl:operation>
	</wsdl:portType>

	<wsdl:binding name="serviceSOAP" type="tns:service">
		<soap:binding style="document" transport="http-~~-//schemas.xmlsoap.org/soap/http"/>

		<wsdl:operation name="getProductByID">
			<soap:operation soapAction="urn:Rodrigo/service/getProductByID"/>
			<wsdl:input>
				<soap:body use="literal"/>
			</wsdl:input>

			<wsdl:output>
				<soap:body use="literal"/>
			</wsdl:output>
		</wsdl:operation>

		<wsdl:operation name="getProductsByFilial">
			<soap:operation soapAction="urn:Rodrigo/service/getProductsByFilial"/>
			<wsdl:input>
				<soap:body use="literal"/>
			</wsdl:input>

			<wsdl:output>
				<soap:body use="literal"/>
			</wsdl:output>
		</wsdl:operation>
	</wsdl:binding>

	<wsdl:service name="service">
		<wsdl:port binding="tns:serviceSOAP" name="serviceSOAP">
			<soap:address location="http-~~-//localhost/webservice/"/>
		</wsdl:port>
	</wsdl:service>
</wsdl:definitions>

 

 

 

Supondo que você tenha colocado seu arquivo service.wsdl dentro da pasta public, teremos a seguinte estrutura:

 

/

/index.php

/application

/application/db

/application/db/DatabaseConnectionInfo.php

/application/db/MySQLConnectionInfo.php

/application/product

/application/product/Product.php

/application/product/ProductCharacteristic.php

/application/product/ProductList.php

/application/Server.php

/application/Service.php

/public/service.wsdl

 

Bom, como o primeiro passo do nosso cliente é acessar o WSDL, vamos deixá-lo acessível:

 

/index.php

<?php
$wsdl = 'public/service.wsdl';

if ( isset( $_GET[ 'WSDL' ] ) ){
	header( sprintf( '%s 200 Ok' , $_SERVER[ 'SERVER_PROTOCOL' ] ) );
	header( 'Content-Type: text/xml; charset=UTF-8' ); //application/wsdl+xml
	header( sprintf( 'Content-Length: %d' , filesize( $wsdl ) ) );

	readfile( $wsdl );
} else {
	require 'application/Server.php';
	require 'application/Service.php';
	require 'application/db/MySQLConnectionInfo.php';

	$server = new Server( $wsdl , new Service( new MySQLConnectionInfo( '127.0.0.1' , 'nome_do_banco' , 'usuario' , 'senha' ) ) );
	$server->handle();
}

 

Ok, se for requisitado o WSDL, mostramos o arquivo, caso contrário, chamamos o servidor:

 

/application/Server.php

<?php
/**
* Exemplo de webservices em PHP usando SOAP
*/
class Server {
	/**
	 * @var SoapServer
	 */
	private $soap;

	/**
	 * @param string $wsdl Caminho para a descrição do serviço
	 * @param Service $service O objeto que será utilizado nas requisições
	 */
	public function __construct( $wsdl , Service $service ){
		$this->soap	= new SoapServer(
			$wsdl,
			array(
				'exceptions'	=> 1,
				'style'			=> SOAP_DOCUMENT,
				'use'			=> SOAP_LITERAL,
				'soap_version'	=> SOAP_1_1,
				'encoding'		=> 'UTF-8'
			)
		);

		$this->soap->setObject( $service );
	}

	/**
	 * Recebe e manipula as requisições
	 */
	public function handle(){
		$this->soap->handle();
	}
}

 

Veja que nosso servidor é bastante simples, agora, nosso serviço:

 

/application/Service.php

<?php
require 'application/product/Product.php';
require 'application/product/ProductList.php';

/**
* Um serviço simples
*/
class Service {
	/**
	 * @var PDO
	 */
	private static $pdo;

	/**
	 * @var DatabaseConnectionInfo
	 */
	private $info;

	public function __construct( DatabaseConnectionInfo $info ){
		$this->info = $info;
	}

	/**
	 * Recupera um produto pelo ID
	 * @param stdClass $request Um objeto contendo a propriedade idProduto
	 * @return Product
	 */
	public function getProductByID( $idProduct ){
		$pdo = $this->getPDO();
		$stm = $pdo->prepare( 'SELECT `productName`,`productValue`,`productHeight`,`productWeight` FROM `Product` AS `p` WHERE `p`.`idProduct`=:idProduct;' );
		$stm->bindParam( ':idProduct' , $idProduct , PDO::PARAM_INT );

		if ( $stm->execute() ){
			if ( ( $product = $stm->fetch( PDO::FETCH_OBJ ) ) !== false ){
				return new Product( $product->productName , $product->productValue , $product->productHeight , $product->productWeight );
			} else {
				throw new SoapFault( 'P1' , 'Produto não cadastrado.' );
			}
		} else {
			throw new SoapFault( 'P0' , 'Não foi possível recuperar o produto.' );
		}
	}

	/**
	 * Recupera um produto pelo id da Filial
	 * @param stdClass $request Um objeto contendo a propriedade idFilial
	 * @return Produto
	 */
	public function getProductsByFilial( $idFilial ){
		$pdo = $this->getPDO();
		$stm = $pdo->prepare( 'SELECT `p`.`productName`,`p`.`productValue`,`p`.`productHeight`,`p`.`productWeight` FROM `Filial` AS `f` LEFT JOIN `Product` AS `p` USING(`idFilial`) WHERE `f`.`idFilial`=:idFilial;' );
		$stm->bindParam( ':idFilial' , $idFilial , PDO::PARAM_INT );

		if ( $stm->execute() ){
			$list = new ProductList();

			foreach ( $stm->fetchAll( PDO::FETCH_OBJ ) as $product ){
				$list->addProduct( new Product( $product->productName , $product->productValue , $product->productHeight , $product->productWeight ) );
			}

			return $list;
		} else {
			throw new SoapFault( 'P2' , 'Não foi possível recuperar a lista de produtos da filial' );
		}
	}

	/**
	 * Recupera a instância de PDO
	 * @return PDO
	 */
	private function getPDO(){
		if ( is_null( self::$pdo ) ){
			self::$pdo = new PDO( $this->info->getDSN() , $this->info->getUser() , $this->info->getPswd() );
		}

		return self::$pdo;
	}
}

 

Bom, deixamos o acesso a dados aqui dentro mesmo para simplificar o exemplo, o DatabaseConnectionInfo fica assim:

 

/application/db/DatabaseConnectionInfo.php

<?php
interface DatabaseConnectionInfo {
	public function getDSN();
	public function getPswd();
	public function getUser();
}

 

E a MySQLConnectionInfo assim:

 

/application/db/MySQLConnectionInfo.php

<?php
require 'application/db/DatabaseConnectionInfo.php';

class MySQLConnectionInfo implements DatabaseConnectionInfo {
	private $host;
	private $name;
	private $pswd;
	private $user;

	public function __construct( $host , $name , $user , $pswd ){
		$this->host = $host;
		$this->name = $name;
		$this->pswd = $pswd;
		$this->user = $user;
	}

	public function getDSN(){
		return sprintf( 'mysql:host=%s;dbname=%s' , $this->host , $this->name );
	}

	public function getPswd(){
		return $this->pswd;
	}

	public function getUser(){
		return $this->user;
	}
}

 

Agora nossos Product, ProductCharacteristic e ProductList:

 

/application/product/Product.php

<?php
require 'application/product/ProductCharacteristic.php';

class Product {
	public $productName;
	public $productValue;
	public $productCharacteristic;

	public function __construct( $name , $value , $height , $weight ){
		$this->productName = $name;
		$this->productValue = $value;
		$this->productCharacteristic = new ProductCharacteristic( $height , $weight );
	}
}

 

/application/product/ProductCharacteristic.php

<?php
class ProductCharacteristic {
	public $productHeight;
	public $productWeight;

	public function __construct( $height , $weight ){
		$this->productHeight = (float) $height;
		$this->productWeight = (float) $weight;
	}
}

 

/application/product/ProductList.php

<?php
class ProductList {
	public $items = array();

	public function addProduct( Product $product ){
		$this->items[] = $product;
	}
}

 

Com isso, temos o servidor completo, fazendo um teste:

 

<?php
$wsdl = 'http-~~-//localhost/webservice/index.php?WSDL';

$client = new SoapClient(
	$wsdl,
	array(
		'exceptions'	=> 1,
		'style'			=> SOAP_DOCUMENT,
		'use'			=> SOAP_LITERAL,
		'soap_version'	=> SOAP_1_1,
		'encoding'		=> 'UTF-8'
	)
);

try {
	$response = $client->getProductByID( 1 );

	var_dump( $response ); //vai exibir a resposta
} catch ( SoapFault $f ){
	echo 'Opz, ' , $f->getMessage();
}

 

A saída será:

object(stdClass)#2 (3) {
	["productName"]=>
	string(11) "Notebook HP"
	["productValue"]=>
	float(2550)
	["productCharacteristic"]=>
	object(stdClass)#3 (2) {
		["productHeight"]=>
		float(15)
		["productWeight"]=>
		float(1.2)
	}
}

Agora, usando o outro método:

 

try {
	$response = $client->getProductsByFilial( 1 );

	var_dump( $response ); //vai exibir a resposta
} catch ( SoapFault $f ){
	echo 'Opz, ' , $f->getMessage();
}

 

A saída será:

 object(stdClass)#2 (1) {
 ["items"]=>
 array(3) {
 [0]=>
 object(stdClass)#3 (3) {
 ["productName"]=>
 string(11) "Notebook HP"
 ["productValue"]=>
 float(2550)
 ["productCharacteristic"]=>
 object(stdClass)#4 (2) {
 ["productHeight"]=>
 float(15)
 ["productWeight"]=>
 float(1.2)
 }
 }
 [1]=>
 object(stdClass)#5 (3) {
 ["productName"]=>
 string(9) "iMac 21.5"
 ["productValue"]=>
 float(3900)
 ["productCharacteristic"]=>
 object(stdClass)#6 (2) {
 ["productHeight"]=>
 float(60)
 ["productWeight"]=>
 float(4)
 }
 }
 [2]=>
 object(stdClass)#7 (3) {
 ["productName"]=>
 string(5) "Mouse"
 ["productValue"]=>
 float(29)
 ["productCharacteristic"]=>
 object(stdClass)#8 (2) {
 ["productHeight"]=>
 float(5)
 ["productWeight"]=>
 float(0.2)
 }
 }
 }
 }

;)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cara, nem sei como te agradecer! Seguindo suas instruções consegui fazer o servidor web service funcionar perfeitamente do jeito que eu precisava! Percebi que se o WSDL não bater perfeitamente com o método nada vai funcionar, então já comecei a estudar sobre a escrita do WSDL e XML Schema, aliás, escrever na mão é muito melhor do que utilizar scripts de terceiros, pelo menos no PHP.

 

Bom, por mim o tópico já está resolvido! Qualquer coisa volto a postar por aqui!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Amigos preciso da ajuda de vocês, todos os tutoriais que encontrei na internet sobre WebServices com PHP retornam Arrays, é possível faze-lo retornar XML, estou a dias brigando com o nuSoap mais não consigo. Gostaria de retornar um XML nessa estrutura:

<?xml version="1.0"?>

<Pedidos>

<Pedido>

<id>10</id>

<vendedor>1</vendedor>

<medico>1</medico>

<cliente>2</cliente>

<convenio>BLA</convenio>

<data_cirurgia>2011-08-22</data_cirurgia>

<numero_controle>123</numero_controle>

<paciente>João da Silva</paciente>

<data_pedido>2011-08-21 02:31:05</data_pedido>

<ItensPedidos>

<ItemPedido>

<id_item>22</id_item>

<pedido>10</pedido>

<produto>3</produto>

<quantidade>50</quantidade>

</ItemPedido>

<ItemPedido>

<id_item>23</id_item>

<pedido>10</pedido>

<produto>2</produto>

<quantidade>10</quantidade>

</ItemPedido>

</ItensPedidos>

</Pedido>

</Pedidos>

 

Preciso que seja retornado um XML, porque meu cliente utiliza um sistema que só consegue ler se for XML.

Utilizo o framework MVC Codeigniter + NuSoap. Acredito que o problema esteja na definição do WSDL, hoje eu tenho praticamente 4 ComplexTypes: Pedidos, Pedido, Itens de Pedido e Item de Pedido.

 

Não sei se é a forma mais coerente de mapear isso, se vocês puderem me dar alguma dica, pois já esgotei minhas fontes sobre o assunto.

 

Desde já agradeço.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.