Rotas no ZF2

Bom dia pessoal!

Atendendo a pedidos, hoje vou falar sobre rotas no zf2.

Basicamente, uma rota define qual Controller/Action será chamado para determinado endereço OU parâmetros na linha de comando no caso de “console routes”.

Para este post, vamos assumir que você instalou a Zend Skeleton Application, manualmente ou pelo zftool e configurou seu acesso para http://localhost/teste .

Mas como configurar uma rota? Isso é feito em cada módulo, ou seja, cada um é responsável pelas suas próprias rotas. Você pode olhar o conteúdo do arquivo “module/Application/config/module.config.php”:

As partes marcadas mostram as rotas. A primeira, iniciando na linha 11, mostra as rotas via página e a segunda, iniciando na linha 96, as rotas para o console (vou falar sobre Controllers de console num post em breve). Mas vamos examinar cada pedaço.

Primeiro definimos um nome para a rota (“home” na linha 1), seu tipo (“literal” na linha 2″). Na parte de opções, temos a rota em sí, que neste caso é “/”, ou seja, a raiz da nossa aplicação, e será chamado o controller Index (module/Application/src/Application/Controller/IndexController.php) e a ação index (IndexAction dentro do controller).

Então sempre que acessarem a raiz da nossa aplicação (http://localhost/teste) o ZF2 irá buscar pela rota responsável pelo “/” e chamará o controller/action correspondentes.

Mas o que acontece se um outro módulo definir uma rota chamada “home” ou uma rota “/”? Bem, aí teremos um sobrescrevendo o outro, apenas um deles irá funcionar. Qual deles? Depende da configuração dos seus módulos.

Se olharmos o arquivo “config/application.config.php”:

Vemos que o primeiro módulo chamado é  o Application, mas se definirmos uma rota “/” no módulo MeuModule está que será usada, pois foi definida depois (supondo que você não tenha usado prioridade de módulos, papo para outro post).

Mas voltando para as rotas da nossa aplicação:

O início é bem parecido com o de cima. Será chamada sempre que o endereço iniciar por “/application”. Sem nada depois será executado o controller Index/action Index. Mas nesta rota foi definido o namespace, com isso não precisamos definir o caminho todo do controller nesta rota e todas as suas filhas.

Esta rota possui filhas, sendo a primeira e única definida como um segmento (Segment) e na linha 16 o caminho usado. Vou falar sobre o segmento mais abaixo, mas por enquanto basta saber que esta rota será chamada para por exemplo:

As mesmas regras valem para chamadas pelo console. Não vou entrar  em detalhes sobre o console, pois vou fazer um post só sobre isso, mas você pode definir uma rota por exemplo:

Se executarmos no console:

Irá executar o controller Index, action lista, se o controller tiver sido definido como controller também de console (post futuro).

Tipos de rotas

Existem vários tipos de rota:

  • Hostname
  • Literal
  • Method
  • Part
  • Regex
  • Scheme
  • Segment

Os mais usados são Literal, Regex e Segment, mas vou falar um pouco sobre cada um.

Hostname

Usando este tipo, você pode chamar uma rota dependendo do hostname. Considere estas rotas:

As 2 definem rotas para “/”, mas a diferença está no hostname.

Se for chamado http://dominio1.com.br irá ser roteado para o controller Index, action Index, mas se o acesso for htto://dominio2.com.br, irá para a action Index2.

Literal

Já vimos esta rota nos exemplos anteriores. Ela leva em consideração o caminho exato, sem parâmetros:

Esta rota irá funcionar APENAS para http://localhost/teste/lista. Por exemplo, http://localhost/teste/lista/1 não vai funcionar, pois a rota precisa ser exata.

Method

Será usada quando o método da chamada for definido:

Aqui, se acessarmos http://localhost/teste/lista irá para o controller Index, action “lista”, mas se o acesso for POST (por exemplo, submetendo um formulário com post), irá para action “salva”.

O mais importante aqui é definirmos o may_terminate da linha 10 como false. 

O “may_terminate” diz para o sistema de roteamento se ele deve parar de procurar rotas filhas ou não. Se aqui definirmos como “true”, a action salva nunca será chamada, pois ele já vai parar na primeira rota.

Part

Na verdade já estamos usando este método sem saber. Quando definimos o array no arquivo de configuração do módulo da ZendSkeletonApplication, este array é uma rota do tipo part, mas sem definição explícita. Isso porque as rotas definidas usam a TreeRouteStack e não a SimpleRouteStack. A diferença básica é que a Tree permite você criar uma árvore de rotas, com filhas, etc. Já a Simple não. Como a grande maioria das aplicações possuem rotas filhas, usaremos muito a TreeRouteStack

Sempre que você definir no array chave “child_routes”, ela se tornará automaticamente uma rota do tipo “Part”.

Regex

Este tipo usa expressões regulares para achar a rota:

Aqui ele irá funcionar, por exemplo, com:

 Scheme

Este tipo leva em consideração apenas se o acesso foi via http ou https:

As duas rotas buscam o “/”, mas se o acesso for http irá para a action “lista”, se for https vai para “lista2”.

Segment

Este tipo é muito usado, pois permite passar parâmetros para a action. Por exemplo, no arquivo do módulo Application:

Aqui o roteador irá achar por:

Mas não por:

Para chegar nesta rota, o segmento deve começar com “/lista” e pode ter ATÉ 2 parâmetros, mas pode não ter nenhum. E obrigatoriamente o primeiro será a página e deve ser numérica e o segundo o tipo que deverá começar por uma letra. Nos 2 casos acima esta rota não irá ser achada pela “lista”, mas pode existir em outra rota, senão irá dar um erro de rota desconhecida, gerando um 404.

Os parâmetros poderão ser usados dentro das actions usando:

O segundo argumento da função getParam define o padrão caso o valor buscado não exista. Como na rota definimos já definimos um padrão (chave “default”), os 2 parâmetros sempre vão existir, então definí-los aqui é redundante.

Nos exemplos acima (os 3 que funcionam) teremos respectivamente:

Até a próxima!

Leandro Silva

PHP developer since 1997, loves movies, music and dogs.

8 Comentários para: “Rotas no ZF2

  1. No caso, para eu ter links como por exemplo: /item/galinha+com+bico/page/2, qual das rotas eu utilizaria? Uma regex, pelo fato de estar substituindo os espaços por +? ou uma segment já daria conta do recado?

  2. Parabéns pelo post. Tenho uma dúvida se puder me ajudar. Estou trabalhando em uma aplicação com AngularJS e Zend 2, então a página inicial do meu projeto não é definida por um controller e uma action, é uma página estática html mesmo em public/app/index.html. Como eu faço para colocar esta página como inicial?

    Obrigado.

    • Olá Jonathan! Obrigado! Normalmente nos meus projetos coloco a página inicial, mesmo que seja só html dentro do projeto em module/Application/view/application/index/index.phtml pois tenho melhor controle, inclusive de layout padrão, bibliotecas etc.

      • No meu caso deixar a página dentro do view não ajuda pois para alcançá-la eu necessariamente tenho que passar pelo controller para me redirecionar. No caso eu estou usando Angular, então os meus controllers são fazem nada a não ser enviar e receber JSON por meio de chamadas POST e GET. O template também é controlado pelo Angular. Então as minhas páginas precisam estar em public para que eu possa acessá-las diretamente sem passar pelos controllers do Zend. No JSF em java eu consigo este comportamento fácil pois naturalmente ele acessa páginas e não controllers como acontece no Zend e no .NET MVC. Eu consigo este comportamento acessando diretamente no navegador, mas não encontro um meio de deixar este comportamento padrão, ou seja, deixar a pasta em public/app/index.html a página inicial do sistema.

Deixe uma resposta

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

*