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.
< ?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.