Escrevendo URLs no Zend Framework
Posted on December 30th, 2008 in Framework, Php, Tecnologia | 4 Comments »
O Zend Framework, assim com os demais frameworks que utilizam o padrão MVC, possui uma estrutura de roteamento para mapear e direcionar corretamente os seus controles e ações de acordo com determinada url requisitada pela aplicação. Também como os demais, possibilita a escrita de urls para estes controles na camada de visualização quando necessário, através dos “helpers”.
Infelizmente, o helper responsável pela escrita dessas urls ainda é bastante imaturo. A forma como deve ser feita esta tarefa é trabalhosa, chata e principalmente, improdutiva. Só o fato de ter de indicar “TODOS” os parâmetros para a escrita da URL em uma estrutura de array associativa soa como um paradoxo, já que o próprio framework possui mecanismos que fazem o parser na url requisitada, identificando os parâmetros necessários e passando-os ao roteador. Ou seja, é um retrabalho e não um reúso. Exemplo de uma url escrita da forma padrão em um arquivo de template.
<?php
echo $this->url(array( 'controller' => 'users', 'action' => 'edit', 'id' => 25 ));
?>
A saída do exemplo será: /users/edit/id/25. Analisando a url, seria mais fácil simplesmente escrever da seguinte forma:
<?php
echo "/users/edit/id/25";
?>
Desta forma o resultado é mais rápido, porém, você perde em termos controle, já que a escrita é manual e se você alterar o nome do controle ou da ação, a url passará a ser inválida (a não ser que você use roteadores customizados).
A maioria dos frameworks, como Symfony, Cake etc, implementam tanto a forma de escrita com os parâmetros em um array, quanto uma string contendo a url desejada, fazendo a conversão automática dos mesmos para o formato padrão do framework ou da aplicação. O Symfony, por exemplo, implementa a escrita da seguinte forma:
<?php echo url_for('users/edit?id='. 25); ?>
O Symfony automaticamente converterá isso para o formato /users/edit/id/25. Considero essa forma muito mais elegante e produtiva, pois está mais próximo da realidade das urls “dinâmicas”. No entanto, se houver mais parâmetros, a coisa já começa a complicar.
Voltando a forma como o Zend Framework implementa este recurso, já se sabe que ele não é tão flexível assim, então é necessário criar um helper na camada de visualização para esta tarefa. Podemos inclusive, aproveitar o que já foi desenvolvido e é padrão do framework e encontra-se na pasta: Zend/View/Helper/Url.php.
#Zend/View/Helper/Url.php
class Zend_View_Helper_Url extends Zend_View_Helper_Abstract
{
public function url(array $urlOptions = array(), $name = null, $reset = false, $encode = true)
{
$router = Zend_Controller_Front::getInstance()->getRouter();
return $router->assemble($urlOptions, $name, $reset, $encode);
}
}
Crie um arquivo de helper com o nome que você quiser e o coloque no diretório de helpers da sua aplicação. O meu eu chamei de MyUrl.php. Crie neste arquivo a classe Zend_View_Helper_MyUrl. Dentro da classe, crie o método myUrl. É importante ressaltar que o nome do helper deve estar no nome do arquivo, como sufixo do nome da classe e como método principal, que é avaliado e chamado pelo objeto Zend_View ao ser requisitado no template.
O método myUrl terá os mesmos parâmetros do helper Url, com exceção que o primeiro parametro poderá tanto ser uma string quanto um array, então não é necessário tipá-la.
A classe então terá a seguinte estrutura.
<?php
require_once 'Zend/View/Helper/Abstract.php';
class Zend_View_Helper_MyUrl extends Zend_View_Helper_Abstract
{
/**
* Return the URL
*
* @param string|array $urlOptions
* @param string $name
* @param bool $reset
* @param bool $encode
* @return string
*/
public function myUrl($urlOptions, $name = null, $reset = false, $encode = true)
{
$front = Zend_Controller_Front::getInstance();
$router = $front->getRouter();
if (is_string($urlOptions)) {
$urlOptions = '/'. ltrim($urlOptions, '/'); // Case the first character is a '?
$request = new Zend_Controller_Request_Http(); // Creates a cleaned instance of request http
$request->setBaseUrl($front->getBaseUrl());
$request->setRequestUri($urlOptions);
$route = $router->route($request); // Return the request route with params modifieds
$urlOptions = $route->getParams();
}
return $router->assemble((array) $urlOptions, $name, $reset, $encode);
}
}
Salvo o helper, é só utilizá-lo. Agora ele suporta todos os formatos:
<?php echo $this->myUrl(array( 'controller'=> 'users, 'action' => 'edit, 'id' => 25 )); ?>
ou
<?php echo $this->myUrl('users/edit?id=25'); ?>
ou
<?php echo $this->myUrl('users/edit/id/25'); ?>
Muito mais simples, elegante e bem produtivo!
É possível ainda utilizar os outros parâmetros do helper padrão, como o nome do roteador a ser utilizado para formatar a url, se o mesmo vai ou não utilizar a url base ou somente a partir da atual e se a url será codificada ou não – bastante útil para utilizar como valor de outros parametros.
Até a próxima.
Tags: Framework, Framework, Helper, Php, Php, Tecnologia, Url, View, Zend, Zend Framework
4 Responses
Muito interessante! Não costumo trabalhar com o Zend, mas andei estudando seu funcionamento. Parabéns pelo artigo!
Gostei! O ZF não é minha ferramenta de opção, mas tive de trabalhar com ele num projeto. Acabamos ficando com as urls literais que era o mais fácil. Sem dúvida, esta dica já teria nos ajudado.
salvou a lavoura
Imagine um analfabeto no linux, tentando instalar e configurar o Zend Framework. Sou eu, estou apanhando feio, 7 x 0 pra instalação. Marcelo, talvez seja ridículo a minha sugestão, mas tenho vasculhado na internet e não consigo encontrar um manual para leigos. A maioria dos conteúdos encontrados de ZF para linux, são abordados com um nível técnico intermediário em Linux.
Como não tenho muita intimidade com o Terminal do Linux, eu não estou conseguindo criar o projeto, configurar o apache e etc.
Sei que é detalhes, mas deixo a uma sugestão!!!
abraços