Webservices com Zend Framework parte I

Posted on dezembro 26, 2011. Filed under: PHP, Zend Framework |

Veja versão deste artigo usando Zend Framework 2:
Webservices SOAP com Zend Framework 2

Introdução

Neste artigo vamos abordar a criação e utilização de webservices SOAP usando Zend Framework. Procurei dividir este artigo em 3 posts. Primeiro post vamos abordar o protocolo SOAP, no segundo post vamos abordar o protocolo REST e no terceiro post iremos abordar algumas das principais APIs de comunicação através de webservices implementados pelo Zend Framework.

SOAP

SOAP é um protcolo escrito em XML para comunicação entre diferentes aplicações. A comunicação entre serviços usando SOAP é realizada em cima da camada HTTP. SOAP pode ser implemetando em qualquer linguagem (PHP, Java, ASP, .NET, etc.). Dessa forma criamos um canal de comunicação entre aplicações desenvolvidas em linguagens e plataformas diferentes.

Devido a comunicação do SOAP estar em cima da camada HTTP evita que a comunicação seja bloqueada por um firewall ou proxy pois o protocolo HTTP é liberado nas maioria das vezes.

Para que um cliente SOAP acesse um serviço é necessário requisitar primeiramente um arquivo denominado WSDL (Web Services Description Language). O arquivo WSDL especifica todas as funções disponíveis pelo webservice, os tipos de dados dos parâmetros entre outras informações relevantes. Quando criarmos nossos próprios webservices teremos que disponibilizar também um arquivo WSDL.

Zend Framework

O Zend Framework fornece ferramentas importantes para trabalhar com Webservices. Através do componente Zend_Soap_Client podemos consumir Webservices e com o componente Zend_Soap_Server podemos criar nossos próprios webservices de maneira simples e eficaz. Neste artigo vamos demonstar a utilização desses dois componentes. Vamos criar nossos próprios webservices e depois como consumí-los.

Criando nosso Webservice SOAP

Para criação do webservice em SOAP vamos utilizar a classe Zend_Soap_Server. Para que funcione corretamente nosso webservice, precisamos disponibilizar o arquivo WSDL. Apesar de ser possível trabalhar com SOAP sem a utilização de um arquivo WSDL, conhecido como modo não WSDL (non-WSDL mode), onde no PHP é possível, porém não aconselhado. A maioria das linguagens de programação exigem a utilização de um arquivo WSDL.

O código abaixo é responsável pela criação de nosso webservice. Vamos disponibilizar os métodos soma e subtrai através da classe Calculadora:

<?php 
/* incluir as classes necessoarias */ 
require_once("Zend/Soap/Server.php"); 
require_once("Zend/Soap/AutoDiscover.php"); 

if(isset($_GET['wsdl'])) {         
        /*          
         * Usar o Soap AutoDiscover para criacao do WSDL de forma dinamica          
         */         
        $autodiscover = new Zend_Soap_AutoDiscover();         
        $autodiscover->setClass('Calculadora');
        $autodiscover->handle();
} else {
        // Disponibilizar o webservice atraves do canal:
        $soap = new Zend_Soap_Server("http://127.0.0.1/soap/soap.php?wsdl");
        $soap->setClass('Calculadora');
        $soap->handle();
}

/*
 * Classe calculadora
 */
class Calculadora {

        /**
         * Realiza Soma
         * @param integer $a
         * @param integer $b
         * @return integer
         */
        public function soma($a, $b) {
                return $a + $b;
        }

        /**
         * Realiza Subtracao
         * @param integer $a
         * @param integer $b
         * @return integer
         */
        public function subtrai($a, $b) {
                return $a - $b;
        }
}

Pontos interssantes à observar no webservice acima:

  • Zend_Soap_AutoDiscover é responsável pela criação dinâmica do WSDL, poupando nosso tempo de ter que criar o WSDL na mão, que é muito trabalhoso.
  • Os blocos de comentário na classe Calculadora ajudam o AutoDiscover na criação do WSDL.

Criando o cliente

Vamos criar um webservice client que irá consumir nosso webservice criado anteriormente:

<?php 
/* incluir classes necessarias */ 
require_once("Zend/Soap/Client.php"); 

/* canal de chamada para webservice */ 
$soap = new Zend_Soap_Client("http://127.0.0.1/soap/soap.php?wsdl"); 

echo $soap->soma(11, 2) . PHP_EOL; // imprime 3
echo $soap->subtrai(11, 2) . PHP_EOL; //imprime 9

Até o próximo. Sucesso!

Make a Comment

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google

Você está comentando utilizando sua conta Google. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s

36 Respostas to “Webservices com Zend Framework parte I”

RSS Feed for Pasqua Tecnologia Comments RSS Feed

Mais um bom post sobre zend, muito bom Douglas!

Esta dando o seguinte erro:

Warning: require_once(Zend/Server/Interface.php) [function.require-once]: failed to open stream: No such file or directory in D:\SERVIDOR\wamp\www\webservice\Zend\Soap\Server.php on line 25

Fatal error: require_once() [function.require]: Failed opening required ‘Zend/Server/Interface.php’ (include_path=’.;C:\php5\pear’) in D:\SERVIDOR\wamp\www\webservice\Zend\Soap\Server.php on line 25

Provavelmente a pasta do Zend não esta no include_path do PHP. Vejo duas alternativas. 1 – Colocar a pasta “D:\SERVIDOR\wamp\www\webservice\” dentro do include_path no php.ini. Por exemplo, no caso do windows (localizar a linha do include_path no seu php.ini):

include_path = “.;D:\SERVIDOR\wamp\www\webservice”

2 – ou transferir o seu script php para dentro da pasta webservice, caso ainda não esteja.

Estão ambos na pasta webservice no diretorio www

Só para tirar a prova dos nove…

1) Inclua o diretório citado anteriormente no include_path do php, no arquivo php.ini conforme descrito. Após alterar o php.ini é preciso reiniciar o apache.
2) Verifique se o arquivo D:\SERVIDOR\wamp\www\webservice\Zend\Server\Interface.php realmente existe.

Cara quando eu acesso meu client para tentar ver os retornos olha oq aparece:

Fatal error: SOAP-ERROR: Parsing WSDL: Couldn’t load from ‘http://start.local/index/webserv?wsdl’ : XML declaration allowed only at the start of the document in /var/www/start/library/Zend/Soap/Client/Common.php on line 51

sabe o que pode ser?

Antes de mais nada parabéns pelo post

Olá Victor,

Segue minhas dicas:

Quando você acessa o link do WSDL diretamente pelo navegador, você visualiza o conteúdo do WSDL corretamente ? (Deve retornar um XML). Senão estiver retornando o XML do WSDL tem que rever seu código SOAP.

Outra dica, andei pesquisando sobre esse erro e alguns dizem sobre um bug na extensão do SimpleXML do PHP. Portanto, aconselho você à atualizar sua versão do PHP e tentar novamente.

Obrigado e Boa Sorte!

Olá, primeiramente parabéns pelo post! Eu estava procurando uma solução simples como o NuSoap, porém mais atual, e isso caiu certinho! Porém surgiu-me uma dúvida! Pelo que eu entendi, essa classe é implementada com o framework Zend, eu não uso Zend, uso o Symfony, e eu não gosto de gerar o WSDL(nunca consegui na verdade), preciso de algo simples, como esse exemplo! Quero saber se posso usar essas classes mesmo fora do framework? Ou elas são herdadas de classes maiores e maiores dentro do framework?

Obrigado pelo contato Paulo.
Você pode usar os componentes do zend framework separadamente da sua estrutura MVC como se fossem uma lib qualquer. Esse é um dos grandes atrativos do framework da Zend.Portanto, a única coisa que precisa fazer é baixar o framework da zend, mover o diretório lib/Zend para dentro do seu include_path e utilizar as classes do Zend_Soap como esta explicado no artigo. Acredito que pode fazer isso dentro do Symfony sem problemas. Você vai ter a pasta do zend framework completa no seu include_path, mas irá usar um somente um componente.

Opa, fiz o que vc me sugeriu e funcionou certinho ^^ porém descobri que o symfony tem um plugin que faz isso tbm, lá vou eu mudar de novo, mas mesmo assim obrigado, em aplicações fora do symfony, concerteza é a melhor solução, obrigado pela ajuda.

Muito obrigado pelo artigo! Ajudou bastante!

Obrigado Rodrigo! Boa sorte!

Olá, obrigado pelo post!
Você poderia explicar como passar um parâmetro de tipo array em uma das public functions?
Obrigado!

Olá Rodrigo,

Acredito que o exemplo abaixo possa ajudar a resolver o seu problema:

/**
 * Realiza Soma baseado nos valores do array de input
 * @param array $valores
 * @return integer
 */
public function soma(array $valores) {
// tratar logica...
}

Boa sorte!

Obrigado!
Copiei todo o diretório Zend para meu servidor, onde eu rodo meu site PHP.
Copiei o código exemplo que você escreveu. Está dando o erro:
“Parse error: syntax error, unexpected T_STRING in …/Zend/Soap/Server.php on line 10”

A versão do PHP no meu servidor é PHP Version 5.2.17 rodando em Linux (Locaweb).
Olhei dentro do arquivo “Zend/Soap/Server.php” e na linha 10 tem o comando:
namespace Zend\Soap;

Já passou por isto? Tem alguma ideia?

Obrigado!

Olá Rodrigo,

Você baixou a versão 2.x do Zend Framework! A partia da versão 2 do Zend Framework houve uma grande reestruturação no projeto. Portanto, a versão mínima para rodar o ZF2 é à partir do PHP 5.3.3 ! Por isso esta gerando esse erro no seu teste.

O código de exemplo que esta no meu artigo, é baseado na versão 1.x do Zend Framework. Portanto, para realizar seus testes, aconselho a usar a versão 1 ! A versão 1 ainda é válida e muitos projetos ainda estão baseados nessa versão. Segue o link para download do Zend Framework 1:

http://framework.zend.com/downloads/latest#ZF1

Boa sorte!

Obrigado de novo 🙂
Eu baixei o Zend 2, fiz todas as alteraçoes de compatibilidade no meu código PHP, mais ou menos 1 tonelada. rs
Seu código de exemplo funciona no Zend 2?

Está dando o erro:
Fatal error: Interface ‘Zend\Server\Server’ not found in…/sis/Zend/Soap/Server.php on line 24
OBRIGADO!

Olá,

Ainda não testei o código desse artigo no Zend 2! Creio que necessitará de ajustes.
Assim que conseguir testar, farei os ajustes a atualizarei o artigo.

Obrigado pelo toque e Boa sorte!

Eu quem agradeço!
Consegui fazer o código funcionar no Zend2, agora é codificar.
OBRIGADO!

Parábens pelo post Douglas.
Estou seguindo o seu tutorial do Devmedia para montar um webservice com SOAP e REST, porém estou com o seguinte problema, esta dando esse erro:

Fatal error: Interface ‘Zend\Server\Client’ not found in C:\xampp\htdocs\Zend\Soap\Client.php on line 22

Estou usando a versão 5.4.7 do PHP.

Poderia me ajudar?

Olá Thalles, Legal que gostou do artigo.

Este artigo foi escrito ainda quando não existia a versão 2.x do Zend Framework. Pelo erro informado, você esta usando a versão 2.x. Há necessidade de vários ajustes para esse script funcionar no Zend Framework 2.x. Porém, nada impede que você use a versão 1.x do framework para criar seu webservice.

Você pode baixar a versão 1.x através do link:
http://framework.zend.com/downloads/latest#ZF1

Assim que possível irei criar um novo post baseado na versão 2.x

Boa sorte!

Agradeço à atenção! 😀

Baixei a versão 1.12.3 do Zend e ao executar a classe cliente para realizar testes o erro que ocorre agora é o seguinte:

Notice: Use of undefined constant SOAP_1_2 – assumed ‘SOAP_1_2’ in C:\xampp\htdocs\clientZend.php on line 12

Fatal error: Uncaught exception ‘Zend_Soap_Client_Exception’ with message ‘SOAP extension is not loaded.’ in C:\xampp\htdocs\Zend\Soap\Client.php:152 Stack trace: #0 C:\xampp\htdocs\clientZend.php(12): Zend_Soap_Client->__construct(‘http://127.0.0….’) #1 {main} thrown in C:\xampp\htdocs\Zend\Soap\Client.php on line 152

Não tenho ideia alguma do que pode ser este erro, por isso nem tentei solucioná-lo.

Poderia mais uma vez me ajudar?

Olá Thalles,

Você precisa habilitar a extensão soap no php.ini.

Abra o arquivo php.ini distribuído junto com o xampp (Provavelmente C:\xampp\php\php.ini). Identifique e descomente a linha abaixo:

extension=php_soap.dll

Boa sorte!

Mais uma vez obrigado!

Estou conseguindo consumir o método do servidor pelo cliente, consigo também visualizar o wsdl do servidor, o único problema é que quando tento visualizar o servidor diretamente (http://localhost/serverZend.php) ele exibe o seguinte XML de erro (acredito eu):

WSDL

SOAP-ERROR: Parsing WSDL: Couldn’t load from ‘http://localhost/serverZend.php?wsdl’ : failed to load external entity “http://localhost/serverZend.php?wsdl”

Poderia me ajudar novamente?

Bom dia Thalles,

Provavelmente o webservice cliente não esta conseguindo se comunicar com a URL http://localhost/serverZend.php?wsdl ! Tente trocar o localhost pelo IP 127.0.0.1, ficando da seguinte forma:
http://127.0.0.1/serverZend.php?wsdl

Boa sorte!

Infelizmente eu troquei para 127.0.0.1 e o erro continuou o mesmo, não sei o que fazer, estou precisando disso pois o webservice será usado para meu TCC…

O que acontece aqui é o seguinte, o servidor está feito, o cliente está feito, o cliente consegue consumir o servidor normalmente, eu consigo visualizar o wsdl do servidor normalmente, o único problema é que quando eu chamo o servidor direto pelo browser (http://localhost/serverZend.php) ai ele mostra um XML com este erro porém se eu chamo o wsdl (http://localhost/serverZend.php?wsdl) ele mostra normal
e se eu chamo o cliente (http://localhost/clientZend.php) ele chama normal e retorna a mensagem de consumo do servidor. Este erro é normal e eu me equivoquei ou não deveria estar ocorrendo mesmo?

Thalles,

De acordo com sua descrição, o webservice esta funcionando corretamente. Acho que pode desconsiderar esse erro, pois o mais importante é que o WSDL esteja retornando corretamente e o seu webservice cliente esta conseguindo consumi-lo normalmente também.

Quando for divulgar seu webservice para outras plataformas poderem consumi-lo basta informar o endereço do WSDL.

Boa sorte!

Nova versão deste artigo usando Zend Framework 2. Confira:
http://wp.me/pdjRF-15c

Olá Diogo,

Estou com um erro que provavelmente é de configuração, mas não consigo descobrir o que é que está acontecendo.

Executei os passos que você definiu e copiei seus códigos para minha IDE.

Quando acesso via Browser o cliente ele responde com o seguinte erro:

Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn’t load from ‘http://127.0.0.1/server.php?wsdl’ : failed to load external entity “http://127.0.0.1/server.php?wsdl”
in /home/maxwell/public_html/ws-sga/Zend/Soap/Client/Common.php:51
Stack trace:
#0 /home/maxwell/public_html/ws-sga/Zend/Soap/Client/Common.php(51): SoapClient->SoapClient(‘http://127.0.0….’, Array)
#1 /home/maxwell/public_html/ws-sga/Zend/Soap/Client.php(1032): Zend_Soap_Client_Common->__construct(Array, ‘http://127.0.0….’, Array)
#2 /home/maxwell/public_html/ws-sga/Zend/Soap/Client.php(1188): Zend_Soap_Client->_initSoapClientObject()
#3 /home/maxwell/public_html/ws-sga/Zend/Soap/Client.php(1112): Zend_Soap_Client->getSoapClient()
#4 /home/maxwell/public_html/ws-sga/cliente.php(18): Zend_Soap_Client->__call(‘nomeUsuario’, Array)
#5 /home/maxwell/public_html/ws-sga/cliente.php(18): Zend_Soap_Client->nomeUsuario(‘201112151349’)
#6 {main}
thrown in /home/maxwell/public_html/ws-sga/Zend/Soap/Client/Common.php on line 51

PS: Não encontrei nenhuma solução na internet.

Desde já obrigado.

Olá Maxwell,

Verificar na configuração do seu php.ini se a diretiva allow_url_fopen esta setada para On

Boa sorte!

Estava off.

Valeu, Obrigado.

o meu codigo esta dando este erro Fatal error: SOAP-ERROR: Parsing WSDL: Couldn’t find in. Isso é proposital eu que coloquei uma url invalida para tratar justamente este erro. Mais não consigo. tenho uma classe webservice onde há um construtor que instacia Zend_Soap_Client. Quando coloco um try cacth para validar não funciona.

try {
$this->service = new Zend_Soap_Client(“http://local.adminwdna.com.br/webservic.php?wsdl”);
} catch (Exception $e) {
$e->getMessage();
}

Como faço para validar se a url é valida ou não.
Abs

Olá Allison,

Muito interessante essa questão. Consegui tratar essa Exception da seguinte forma:

try {
$soap = new Zend_Soap_Client("URL?wsdl");
@$soap->test();

} catch(Exception $e) {
echo $e->getMessage();
}

// continuar

Boa sorte!

Olá encontrei o mesmo problema do Maxxuel, porem o parametro de allow_url_fopen esta setado para on.
Tens idéia?

Olá Adilson,

É importante garantir que o endereço “http://127.0.0.1/server.php?wsdl” esta acessível a partir do servidor onde você esta rodando seu webservice client.

Uma forma de testar a disponibilidade dessa URL a partir do servidor, é usar a função file_get_contents(), da seguinte forma:

file_get_contents("http://127.0.0.1/server.php?wsdl");

Caso houver problema, será gerado um Warning com o erro HTTP referente ao ocorrido.

Boa sorte!


Where's The Comment Form?

Liked it here?
Why not try sites on the blogroll...

%d blogueiros gostam disto: