Controladores y Enrutamiento

Richard Melo

@allucardster

Agenda

  • Qué es un controlador?
  • Clase controller
  • Objeto Response
  • Objeto Request
  • Qué es el enrutamiento?
  • Configuración de Rutas
  • Importar rutas
  • Generar URLs

Qué es un Controlador?

"Es una función PHP encargada de manipular una petición y generar una respuesta"

Ciclo de vida de una petición

// src/Acme/HelloBundle/Controller/HelloController.php
 
namespace Acme\HelloBundle\Controller;
use Symfony\Component\HttpFoundation\Response;
 
class HelloController
{
    public function indexAction()
    {
      return new Response('<html><body>Hello World</body></html>');
    }
}
# app/config/routing.yml
hello:
    path:         /
    defaults:     { _controller: AcmeHelloBundle:Hello:index }

Clase controller de Symfony

// src/Acme/HelloBundle/Controller/HelloController.php
 
namespace Acme\HelloBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
 
class HelloController extends Controller
{
    public function indexAction()
    {
      return new Response('<html><body>Hello World</body></html>');
    }
}

Redireccion

# app/config/routing.yml
hello:
    path:         /hello
    defaults:     { _controller: AcmeHelloBundle:Hello:index }
world:
    path:         /hello/world
    defaults:     { _controller: AcmeHelloBundle:Hello:world }
// src/Acme/HelloBundle/Controller/HelloController.php
namespace Acme\HelloBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
 
class HelloController extends Controller
{
    public function indexAction()
    {
      return $this->redirect($this->generateUrl('world'));
    }

    public function worldAction()
    {
      return new Response('<html><body>Hello World</body></html>');
    }
}

Reenviar

// src/Acme/HelloBundle/Controller/HelloController.php
namespace Acme\HelloBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
 
class HelloController extends Controller
{
    public function indexAction()
    {
      $response = $this->forward('AcmeHelloBundle:Hello:world', array(
          'name'  => $name,
          'color' => 'green'
      ));

      return $response;
    }

    public function worldAction()
    {
      return new Response('<html><body>Hello World</body></html>');
    }
}

Procesando Plantillas

// src/Acme/HelloBundle/Controller/HelloController.php
//...
class HelloController extends Controller
{
    public function indexAction()
    {
      $content = $this->renderView(
        'AcmeHelloBundle:Hello:index.html.twig',
        array('name' => 'Richard')
      );
 
      return new Response($content);
    }
    public function indexAction()
    {
      return $this->render(
        'AcmeHelloBundle:Hello:index.html.twig',
        array('name' => 'Richard')
      );
    }

Gestionando errores

public function indexAction()
{
    $book = // recupera el objeto desde la base de datos
 
    if (!$book) {
        throw $this->createNotFoundException('El libro no existe.');
    }
 
    return $this->render(...);
}
    public function indexAction()
    {
      //...
      throw new \Exception('Algo no ha salido bien.');
    }

Objeto Response

// Crea un response con codigo de estado 200
$response = new Response('Hello world', 200);
// Crea un response JSON con codigo de estado 200
$response = new Response(json_encode(array('name' => $name)));
$response->headers->set('Content-Type', 'application/json');

Objeto Request

use Symfony\Component\HttpFoundation\Request;
 
public function indexAction(Request $request)
{
    // ¿es una petición Ajax?
    $request->isXmlHttpRequest();
 
    $request->getPreferredLanguage(array('en', 'fr'));
 
    // obtiene el valor de un parámetro $_GET
    $request->query->get('page');
 
    // obtiene el valor de un parámetro $_POST
    $request->request->get('page');
}

Qué es el enrutamiento?

"El enrutamiento es un mecanismo que reescribe las URL para simplificar su aspecto."

# app/config/routing.yml
book_show:
    path:      /book/{id}
    defaults:  { _controller: AcmeLibraryBundle:Book:show }
// src/Acme/LibraryBundle/Controller/BlogController.php
 
namespace Acme\LibraryBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
 
class BookController extends Controller
{
    public function showAction($id)
    {
        $book = // usa la variable $id para consultar la base de datos
 
        return $this->render('AcmeLibraryBundle:Book:show.html.twig', array(
            'book' => $book,
        ));
    }
}
# app/config/config.yml
framework:
    # ...
    router:        { resource: "%kernel.root_dir%/../my_config/routing.yml" }

Configuración básica de rutas

homepage:
    path:      /
    defaults:  { _controller: AcmeDemoBundle:Main:homepage }

Rutas con variables

blog_show:
    path:      /blog/{slug}
    defaults:  { _controller: AcmeBlogBundle:Blog:show }

blog_update:
    path:      /blog/{slug}/update
    defaults:  { _controller: AcmeBlogBundle:Blog:update }

Rutas con variables opcionales

blog_list:
    path:      /blog/{page}
    defaults:  { _controller: AcmeBlogBundle:Blog:show, page: 1 }
URL Ruta Parámetros
/blog blog_list {page} = 1
/blog/1 blog_list {page} = 1
/blog/5 blog_list {page} = 5

Rutas con variables opcionales

blog_list:
    path:      /blog/{slug}/{page}
    defaults:  { _controller: AcmeBlogBundle:Blog:show, page: 1 }
URL Ruta Parámetros
/blog/abc blog_list {page} = 1
{slug} = abc
/blog/abc/1 blog_list {page} = 1
{slug} = abc
/blog/abc/5 blog_list {page} = 5
{slug} = abc

Rutas con requisitos

blog_list:
    path:      /blog/{page}
    defaults:  { _controller: AcmeBlogBundle:Blog:show, page: 1 }

blog_show:
    path:      /blog/{slug}
    defaults:  { _controller: AcmeBlogBundle:Blog:show }
URL Ruta Parámetros
/blog blog_list {page} = 1
/blog/abc blog_show {slug} = abc
/blog/abc-2 blog_show {slug} = abc-2
/blog/50 blog_list {page} = 50
blog_list:
    path:      /blog/{page}
    defaults:  { _controller: AcmeBlogBundle:Blog:show, page: 1 }
    requirements:
        page: \d+

blog_show:
    path:      /blog/{slug}
    defaults:  { _controller: AcmeBlogBundle:Blog:show }
URL Ruta Parámetros
/blog blog_list {page} = 1
/blog/abc blog_show {slug} = abc
/blog/abc-2 blog_show {slug} = abc-2
/blog/50 blog_show {slug} = 50
blog_show:
    path:      /blog/{slug}
    defaults:  { _controller: AcmeBlogBundle:Blog:show }

blog_list:
    path:      /blog/{page}
    defaults:  { _controller: AcmeBlogBundle:Blog:show, page: 1 }
    requirements:
        page: \d+

Requisitos HTTP

contact:
    path:     /contact
    defaults: { _controller: AcmeDemoBundle:Main:contact }
    methods:  [GET]

contact_create:
    path:     /contact
    defaults: { _controller: AcmeDemoBundle:Main:create }
    methods:  [POST]

Variables especiales

article_show:
  path:     /articles/{_locale}/{year}/{title}.{_format}
  defaults: { _controller: AcmeDemoBundle:Article:show, _format: html }
  requirements:
      _locale:  en|fr
      _format:  html|rss
      year:     \d+
  • /articles/en/2010/my-post
  • /articles/fr/2010/my-post.rss
  • /articles/en/2013/my-latest-post.html

Importar rutas

# app/config/routing.yml
acme_hello:
    resource: "@AcmeHelloBundle/Resources/config/routing.yml"

Prefijos en las rutas

# app/config/routing.yml
acme_hello:
    resource: "@AcmeBlogBundle/Resources/config/routing.yml"
    prefix: /admin
# src/Acme/BlogBundle/Resources/config/routing.yml

blog_list:
    path:      /blog/{page}
    defaults:  { _controller: AcmeBlogBundle:Blog:show, page: 1 }
    requirements:
        page: \d+

blog_show:
    path:      /blog/{slug}
    defaults:  { _controller: AcmeBlogBundle:Blog:show }
  • /admin/blog/10
  • /admin/blog/abc

Generando URLs

# src/Acme/BlogBundle/Resources/config/routing.yml

blog_show:
    path:      /blog/{slug}
    defaults:  { _controller: AcmeBlogBundle:Blog:show }
class MainController extends Controller
{
    public function showAction($slug)
    {
        // ...
 
        $url = $this->generateUrl(
            'blog_show',
            array('slug' => 'my-blog-post')
        );
        
        // la $url será: /blog/my-blog-post
    }
}

Anotaciones

//...
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

class ArticleController extends Controller
{
    /**
     * @Route(
     *     "/articles/{_locale}/{year}/{slug}.{_format}",
     *     defaults={"_format": "html"},
     *     requirements={
     *         "_locale": "en|fr",
     *         "_format": "html|rss",
     *         "year": "\d+"
     *     }
     * )
     */
    public function showAction($_locale, $year, $slug)
    {
    }
}

Anotaciones

# app/config/routing.yml
app:
    resource: "@AppBundle/Controller/"
    type:     annotation
    prefix: /app

Preguntas?

Muchas Gracias

Controladores y Enrutamiento

By Richard Andres Melo Carrillo

Controladores y Enrutamiento

  • 911