Symfony 2.4, el libro oficial

5.5. Tareas comunes del controlador

Aunque un controlador puede hacer prácticamente cualquier cosa, la mayoría de los controladores siempre se encargan de las mismas tareas básicas. Estas tareas, tales como redirigir a otra página, procesar plantillas y acceder a servicios básicos, son muy fáciles de manejar en Symfony2.

5.5.1. Redirigiendo

Si deseas redirigir al usuario a otra página, utiliza el método redirect():

public function indexAction()
{
    return $this->redirect($this->generateUrl('homepage'));
}

El método generateUrl() es sólo una función auxiliar que genera la URL de una determinada ruta. Para más información, consulta el capítulo de enrutamiento.

Por defecto, el método redirect() produce una redirección temporal de tipo 302. Para realizar una redirección permanente de tipo 301, modifica el segundo argumento:

public function indexAction()
{
    return $this->redirect($this->generateUrl('homepage'), 301);
}

Truco El método redirect() simplemente es un atajo que crea un objeto Response especial que redirige a los usuarios. Su código es equivalente a:

use Symfony\Component\HttpFoundation\RedirectResponse;

return new RedirectResponse($this->generateUrl('homepage'));

5.5.2. Reenviando

También resulta sencillo realizar redirecciones internas hacia otro controlador de la aplicación mediante e, método forward(). En lugar de redirigir el navegador del usuario, se hace una nueva petición interna (en realidad, sub-petición) y se ejecuta el controlador especificado. El método forward() devuelve el objeto Response generado por el segundo controlador:

public function indexAction($name)
{
    $response = $this->forward('AcmeHelloBundle:Hello:fancy', array(
        'name'  => $name,
        'color' => 'green'
    ));

    // puedes seguir modificando la respuesta o
    // devolverla directamente

    return $response;
}

Ten en cuenta que el método forward() utiliza la notación corta habitual para indicar el controlador que se ejecuta. En este caso, la clase controlador de destino será HelloController dentro del bundle AcmeHelloBundle. El array que se pasa como segundo parámetro del método se convierte en los argumentos utilizados en el controlador resultante.

Esta misma sintaxis se utiliza para ejecutar controladores directamente desde las plantillas, tal y como se explicará más adelante. El método del controlador destino debe tener un aspecto como el siguiente:

public function fancyAction($name, $color)
{
    // ... crea y devuelve un objeto Response
}

Como sucede con los argumentos de los controladores y las rutas, el orden de los argumentos para fancyAction no tiene la menor importancia. Symfony2 asocia las claves del array (por ejemplo, name) con el nombre del argumento del método (por ejemplo, $name). Si cambias el orden de los argumentos, Symfony2 continúa pasando el valor correcto a cada variable.

Truco Al igual que otros métodos de la clase base Controller, el método forward sólo es un atajo de la funcionalidad del núcleo de Symfony2. Puedes realizar un forward duplicando la petición actual y ejecutándola mediante el servicio http_kernel, que devuelve un objeto de tipo Response:

use Symfony\Component\HttpKernel\HttpKernelInterface;

$path = array(
    '_controller' => 'AcmeHelloBundle:Hello:fancy',
    'name'        => $name,
    'color'       => 'green',
);
$request = $this->container->get('request');
$subRequest = $request->duplicate(array(), null, $path);

$httpKernel = $this->container->get('http_kernel');
$response = $httpKernel->handle(
    $subRequest,
    HttpKernelInterface::SUB_REQUEST
);

5.5.3.  Procesando plantillas

Aunque no es obligatorio, la mayoría de los controladores acaban su ejecución renderizando una plantilla para generar el código HTML que se devuelve al usuario.

El método renderView() procesa una plantilla y devuelve su contenido renderizado. Así que puedes usar fácilmente una plantilla para generar el contenido del objeto Response:

use Symfony\Component\HttpFoundation\Response;

$content = $this->renderView(
    'AcmeHelloBundle:Hello:index.html.twig',
    array('name' => $name)
);

return new Response($content);

Si lo prefieres, también dispones del método render() para hacer lo anterior en un solo paso, ya que crea un objeto Response y le añade como contenido el resultado de renderizar la plantilla:

return $this->render(
    'AcmeHelloBundle:Hello:index.html.twig',
    array('name' => $name)
);

En ambos casos, la notación utilizada indica que se renderizará la plantilla que se encuentra en el archivo Resources/views/Hello/index.html.twig del bundle AcmeHelloBundle.

El motor de plantillas de Symfony se explica con gran detalle en el capítulo dedicado a las plantillas.

Truco Si lo prefieres, también puedes evitar el uso del método render() utilizando la anotación @Template. Lee la documentación del FrameworkExtraBundle para obtener más detalles.

Truco El método renderView es un atajo para usar el servicio templating, que también puedes utilizar directamente con el siguiente código:

$templating = $this->get('templating');
$content = $templating->render('AcmeHelloBundle:Hello:index.html.twig', array('name' => $name));

5.5.4.  Accediendo a otros servicios

Al extender la clase base del controlador, puedes acceder a cualquier servicio de Symfony2 a través del método get(). Estos son algunos de los servicios comunes que puedes necesitar:

$templating = $this->get('templating');

$router = $this->get('router');

$mailer = $this->get('mailer');

Symfony dispones de infinidad de servicios ya creados, pero también puedes definir tus propios servicios. Para listar todos los servicios disponibles, utiliza el comando container:debug en la consola:

$ php app/console container:debug

Para más información, consulta el capítulo dedicado al contenedor de servicios.