[ Tutorial ] Zend Framework – Parte 04

getRequest, getParam, Routes, Views

Sumário

No a parte anterior de nosso tutorial vimos como criar Rotas, Layouts e aprendemos sobre Views.
Vamos conhecer agora o Objeto Request e aprender como trabalhar com parametros do URL e fazer redirecionamentos baseados em parametros e rever o Layout e Views.

Objeto Request

Antes de prosseguirmos, vamos analisar brevemente um dos objetos mais utilizados pelo Zend, o Request.
Este objeto é um objeto de solicitação muito simples que é passado entre as classes de roteamento, dispatchers e controladoras. Ele empacota os nomes dos modules, controllers, actions e parametros opcionais, assim como o resto das solicitações do ambiente, quer seja HTTP, que é o que nos interessa, e para os mais avançados e curiosos, CLI ou PHP-GTK.

O objeto é passado através de Zend_Controller_Front e está disponível em toda aplicação através da chamada $this->getRequest() e pode ser usado da seguinte forma dentro de nossa aplicação:


// Como citado anteriormente, o método init é o melhor lugar
// para guardarmos configurações e outras variáveis globais 
// aos nossos actions dentro de um controller
// por isto vamos testar nosso controller aqui
public function init()
{ 
    $this->request = $this->getRequest();
}

A partir desta declaração podemos então acessar vários recursos, tais como Nome do Module, Nome do Controller, Nome do Action e obter os Parametros a partir do URL

Vamos testar algumas funcionalidades básicas e já aproveitar para relembrar o Views:


public function init()
{
    $this->request = $this->getRequest();

    // passamos alguns valores para o view
    $this->view->module = $this->request->getModuleName();
    $this->view->controller = $this->request->getControllerName();
    $this->view->action = $this->request->getActionName();
}

Abra o arquivo /modules/default/view/scripts/index.phtml e adicione as linhas:


...
<h2>Teste de Objeto Request</h2>
<strong>Modulo: </strong> <?= $this->module; ?>
<br />
<strong>Controller: </strong> <?= $this->controller; ?>
<br />
<strong>Action: </strong> <?= $this->action; ?>

Acesse o url do projeto e veja que apareceram as informações que o Objeto Request definiu no View de nossa Aplicação.
Agora você começa a entender melhor o funcionamento do VC do MVC.
O que aconteceu aqui foi uma lógica de negócio processada pelo Controller e passada ao View no arquivo de apresentação.

E para verificar que o método init() está disponível em todos actions de sua aplicação faça o mesmo com o action servicos.

Abra o arquivo /modules/default/view/scripts/servicos.phtml e adicione as linhas:


...
<h2>Teste de Objeto Request</h2>
<strong>Modulo: </strong> <?= $this->module; ?>
<br />
<strong>Controller: </strong> <?= $this->controller; ?>
<br />
<strong>Action: </strong> <?= $this->action; ?>

Acesso o url do action http://zend.localhost/servicos
Como você pode ver, os valores passados no método init() para o View permaneceram disponíveis e somente houve uma alteração no valor de action, pois o module e o controller continuam os mesmos.

Obtendo Parâmetros do URL

Como estamos utilizando MVC seria interessante obtermos valores diretamente do URL para operações básicas.
Vamos fazer uma simulação aqui.
Suponhamos que você tenha produtos na página produto que gostaria de acessar pelo ID, que tradicionalmente seria algo do tipo:

http://zend.localhost/produtos?id=1

No nosso caso, para algo mais interessante, queremos aproveitar a deixa dos famosos URL’s limpos e MVC, então gostaríamos de algo assim:

http://zend.localhost/produtos/id/1

Para fazer isto basta construir o URL deste tipo e obter os parâmetros através do objeto Request pelo método getParam(CHAVE).

Como já vimos anteriormente, o zend entende o URL da seguinte maneira:

URL/MODULE/CONTROLLER/ACTION/PARAMETRO1/VALOR1/PARAMETRO2/VALOR2/etc…

Então, no URL http://zend.localhost/produtos/id/1 ID é um parametro com a chave ‘id’.

Vamos utilizar o action produtos para tal simulação e, como não estamos trabalhando com banco de dados ainda, vamos criar um vetor simples contendo alguns produtos:



public function produtosAction()
{
    $produtos = array(
	1 => array( 
            'nome' => 'TV', 
	    'descricao' => 'Descrição da TV aqui'
	),
	2 => array( 
	    'nome' => 'Celular', 
	    'descricao' => 'Descrição do Celular aqui'
	),
	3 => array( 
	    'nome' => 'Notebook', 
	    'descricao' => 'Descrição do Notebook aqui'
	),
	4 => array( 
	    'nome' => 'Aparelho de Som', 
	    'descricao' => 'Descrição do Aparelho de Som aqui'
	),
    );
	
    $id = $this->request->getParam( 'id' );
	
    if( $id != false ) :
    // vamos definir os valore encontrados nas chaves do vetor
    // e passar os mesmos para o View a fim de obter
    // estes valores no arquivo produtos.phtml
    $this->view->nome = $produtos[$id]['nome'];
    $this->view->descricao = $produtos[$id]['descricao'];
    endif;
	
}

Abra o aquivo produtos.phtml dentro da pasta dos views e insira o código abaixo:


<h1><?= $this->contentTitle; ?>
<?php if( $this->id != '' ) : ?>
<h2><?= $this->nome; ?></h2>
<div>
	<?= $this->descricao; ?>
</div>
<?php endif; ?>

Se você acessar o URL http://zend.localhost/produtos?id=1, você vai receber uma bela mensagem de erro informando que a página não existe e que o controlador ‘produtos’ não existe.

Neste caso, como vimos o Zend irá entender o URL da seguinte forma:

 lang="plain
array (
  'controller' => 'produtos',
  'action' => 'id',
  'module' => 'default',
)  

Para resolver isto teríamos que chamar:

http://zend.localhost/index/produtos/id/1

O que nos fez voltar ao maldito ‘index’ no URL novamente.

Então a solução seria criar um Route para este padrão de URL.

No arquivo application.ini no final do bloco de Routes que criamos anteriormente adicione as linhas:

 lang="plain
;produtos/id/
resources.router.routes.produtosId.route = /produtos/id/:id
resources.router.routes.produtosId.defaults.module = default
resources.router.routes.produtosId.defaults.controller = index
resources.router.routes.produtosId.defaults.action = produtos

Atualizado em 16/12/2011: produtosId deve ser o nome do novo roteamento.
Atualizado em 16/12/2011: Código-fonte para download nas partes 5 e 6.

Acesse o URL http://zend.localhost/produtos/id/1 e veja que está acessando agora!
NOTA: Você precisa passar um novo nome para o roteamento de produtos através do ID, no caso, eu nomeei produtosId mas poderia ser qualquer coisa. Lembre-se de sempre dar nomes ÚNICOS para cada roteamento, mesmo que sejam 100 roteamos envolvendo o mesmo controller, todos precisarão ter um nome único.

IMPORTANTE
O que você passar para
resources.router.routes.produtosId.route
Será o que o Zend irá aceitar no URL e o :id é o nome do parametro que queremos passar para o controller. Poderia ser qualquer coisa, e esta seria a chave que obteríamos em :
$this->request->getParam( CHAVE );

Então, se quisermos podemos eliminar totalmente a chave do URL e ficarmos com algo do tipo:
http://zend.localhost/index/produtos/1
Bastaria modificar o roteamento para:

 lang="plain
;produtos/:id
resources.router.routes.produtos.route = /produtos/:id
resources.router.routes.produtos.defaults.module = default
resources.router.routes.produtos.defaults.controller = index
resources.router.routes.produtos.defaults.action = produtos

Mas para fins didáticos, vamos ficar com o /produtos/id/:id e não /produtos/:id

Você pode colocar inúmeros parametros num redirecionamento tal como:

 lang="plain
;/produtos/fab/:fabricante/cat/:categoria/marcar/:marca/mod/:modelo/cor/:cor/
resources.router.routes.produtos.route = /produtos/fab/:fabricante/cat/:categoria/marcar/:marca/mod/:modelo/cor/:cor/
...

Ou simplesmente:

 lang="plain
;/produtos/:fabricante/cat/:categoria/marcar/:marca/mod/:modelo/cor/:cor/
resources.router.routes.produtosEx.route = /produtos/:fabricante/:categoria/:marca/:modelo/:cor/
...

Conclusão

Nesta parte de nosso tutorial conheceu o Objeto Request e aprendeu como obter parametros a partir do URL e como criar um redirecionamento baseado nestes parametros. Na próxima parte veremos como criar Forms e enviar emails com o Zend_Mail.
Abraços do Giba!

9 comentários sobre “[ Tutorial ] Zend Framework – Parte 04”

  1. Giba, tudo bom
    Meu nome é Renato, sou desenvolvedor PHP a 8 anos, e utilizei alguns framework pelo caminho, o ultimo que me identifiquei foi o codeigniter, porem ele ja não esta me atendendo. e por isso estou estudando muito sobre Zend, e seu tutorial é sensacional, com uma ditatica muito boa, diferente de todo os outros que encontrei na net, pratico e objetivo. concerteza vou ficar acompanhando seu blog, continue assim e por favor continue com os post.

    vlw

  2. Primeiro tenho parabenizar pelos ótimos posts, mas também preciso de ajuda.

    Estou seguindo seus tutoriais mas não consegui recuperar os produtos.

    Pensei que fosse algum erro de digitação, então resolvi copiar seu código e mesmo assim não retornou nada.

      1. Grande Giba, primeiro lugar parabéns pelos posts, eles realmente estão sendo muito úteis para mim… agora, assim como o amigo Ricardo, também não consegui recuperar os produtos… o meu código está exatamente igual ao seu, será que faltou alguma configuração no apache, ou coisa parecida, porque no post anterior tive problemas com as views, pois short open tag não estava habilitado no meu php, contudo o echo dessa forma , não funcionava!!! Grande abraço.

        1. Olá, Fábio.
          Obrigado, havia um erro. Já fiz um update no tutorial.
          Procura ali pelas linhas
          Atualização 16/12/2011
          Eu testei aqui e deu problema no meu também, no caso haviam dois roteamentos com o mesmo nome.
          Dá uma olha no post, qualquer coisa baixa novamente o código-fonte na parte 5 ou 6.

          1. Olá Giba, somente hoje tive tempo de verificar o seu post, ficou show de bola, tudo funcionando, faltou apenas passar o parâmetro para a view “$this->view->id = $id;”…faltou só isso para funcionar…
            Abraço.

  3. Po, nunca pensei que programar com Zend Framework era divertido assim, eu achava isso bicho de 7 cabeças, mas to começando a me empolgar com isso. Parabéns Giba, seu tuto esta sendo muito útil para mim e outros que pretendem entrar no mundo dos framework.
    Vlw!

  4. Primeiramente, parabéns pelo tutorial muito bem elaborado, está ajudando bastante!
    Só um detalhe, como o amigo Fábio Ribeiro citou num comentário acima, está faltando a linha “$this->view->id = $id;” na produtosAction().
    Abraços!

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *