Controller
Realizada por:
Diego Barros |@imnzombie
Diego Ramirez |@thedarsideofit
Para: Hydras C&S |@hydras_cs
Basada en L...
¿Qués un controlador?
● Un controlador es una función PHP, que
toma información desde la petición HTTP y
construye una res...
Ciclo de vida de la petición,
controlador, respuesta
1. Cada petición es manejada por un único
archivo controlador frontal...
Ciclo de vida de la petición,
controlador, respuesta
3. El controlador de la ruta encontrada es
ejecutado y el código dent...
Un controlador sencillo
Mientras que un controlador puede ser cualquier ejecutable PHP (una
función, un método en un objet...
Asignando una URL a un controlador
El nuevo controlador devuelve una página HTML simple. Para
realmente ver esta página en...
Recordando:
El controlador tiene un solo argumento, $name, el cual corresponde
al parámetro {name} de la ruta coincidente ...
● El orden de los argumentos del controlador no tiene
importancia
● Cada argumento requerido del controlador debe coincidi...
La Petición como argumento para el
controlador
Para mayor comodidad, también puedes hacer que Symfony pase el
objeto Petic...
La clase base del controlador
Para mayor comodidad, Symfony2 viene con una clase Controller
base, que te ayuda en algunas ...
Tareas comunes del controlador
A pesar de que un controlador puede hacer prácticamente cualquier
cosa, la mayoría de los c...
Reenviando
Además, fácilmente puedes redirigir internamente hacia a otro
controlador con el método forward(). En lugar de ...
Procesando plantillas
Aunque no es un requisito, la mayoría de los controladores en última
instancia, reproducen una plant...
Accediendo a otros servicios
Al extender la clase base del controlador, puedes acceder a cualquier
servicio de Symfony2 a ...
Gestionando errores y páginas 404
Cuando no se encuentra algo, debes jugar bien con el protocolo HTTP
y devolver una respu...
El método createNotFoundException() crea un objeto
NotFoundHttpException especial, que en última instancia,
desencadena un...
Gestionando la sesión
Symfony2 proporciona un agradable objeto sesión que puedes utilizar
para almacenar información sobre...
Mensajes flash
También puedes almacenar pequeños mensajes que se pueden guardar
en la sesión del usuario para exactamente ...
En la siguiente acción de la plantilla, podrías utilizar el siguiente código
para reproducir el mensaje de aviso:
Twig:
PH...
El objeto Respuesta
El único requisito para un controlador es que devuelva un objeto
Respuesta.
La clase SymfonyComponentH...
El objeto Petición
Además de los valores de los marcadores de posición de enrutado, el
controlador también tiene acceso al...
Estructura de directorios:
La estructura de directorios en Symfony2 es bastante flexible:
app: La configuración de aplicac...
1
2
3
4
5
6
7
8
9
// web/app.php
require_once __DIR__.'/../app/bootstrap.php.cache';
require_once __DIR__.'/../app/AppKern...
El directorio app/
La clase AppKernel es el punto de entrada principal para la
configuración de la aplicación y, como tal,...
Comprendiendo el sistema de paquetes(Bundles)
Un paquete es un poco como un complemento en otros programas. Así
que ¿por q...
Registrando un paquete
Una aplicación se compone de paquetes tal como está definido en el
método registerBundles() de la c...
Extendiendo un paquete
Además de ser una buena manera de organizar y configurar tu código,
un paquete puede extender otro ...
Nombres lógicos de archivo
Cuando quieras hacer referencia a un archivo de un paquete, utiliza esta notación:
@NOMBRE_PAQU...
Extendiendo paquetes
Si sigues estas convenciones, entonces puedes utilizar herencia de paquetes para
«redefinir» archivos...
Upcoming SlideShare
Loading in...5
×

Clase 5 controller

154

Published on

www.hydrascs.com

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
154
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
8
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "Clase 5 controller"

  1. 1. Controller Realizada por: Diego Barros |@imnzombie Diego Ramirez |@thedarsideofit Para: Hydras C&S |@hydras_cs Basada en Libro Symfony 2 en español Nacho Pacheco
  2. 2. ¿Qués un controlador? ● Un controlador es una función PHP, que toma información desde la petición HTTP y construye una respuesta y la devuelve (como un objeto Respuesta de Symfony2) ● La respuesta podría ser HTML, XML, JSON, una imagen, una redirección, un error 404 o cualquier otra cosa. ● El controlador contiene toda la lógica arbitraria que tu aplicación necesita para reproducir el contenido de la página.
  3. 3. Ciclo de vida de la petición, controlador, respuesta 1. Cada petición es manejada por un único archivo controlador frontal (por ejemplo,app. php o app_dev.php) el cual es responsable de arrancar la aplicación; 2. El Enrutador lee la información de la petición (por ejemplo, la URI), encuentra una ruta que coincida con esa información, y lee el parámetro _controller de la ruta;
  4. 4. Ciclo de vida de la petición, controlador, respuesta 3. El controlador de la ruta encontrada es ejecutado y el código dentro del controlador crea y devuelve un objeto Respuesta; 4. Las cabeceras HTTP y el contenido del objeto Respuesta se envían de vuelta al cliente.
  5. 5. Un controlador sencillo Mientras que un controlador puede ser cualquier ejecutable PHP (una función, un método en un objeto o un Cierre), en Symfony2, un controlador suele ser un único método dentro de un objeto controlador. Los controladores también se conocen como acciones. 1 2 3 4 5 6 7 8 9 10 11 12 // src/Acme/HelloBundle/Controller/HelloController.php namespace AcmeHelloBundleController; use SymfonyComponentHttpFoundationResponse; class HelloController { public function indexAction($name) { return new Response('<html><body>Hello '.$name.'! </body></html>'); } }
  6. 6. Asignando una URL a un controlador El nuevo controlador devuelve una página HTML simple. Para realmente ver esta página en tu navegador, necesitas crear una ruta, la cual corresponde a un patrón de URL específico para el controlador: # app/config/routing.yml hello: pattern: /hello/{name} defaults: { _controller: AcmeHelloBundle:Hello:index } Si vamos a la url /hello/symfonyanos se ejecuta el controlador HelloController::indexAction() y pasa symfonyanos a la variable $name. Crear una «página» significa simplemente que debes crear un método controlador y una ruta asociada.
  7. 7. Recordando: El controlador tiene un solo argumento, $name, el cual corresponde al parámetro {name} de la ruta coincidente (symfonyanos en el ejemplo). De hecho, cuando ejecutas tu controlador, Symfony2 empareja cada argumento del controlador con un parámetro de la ruta coincidente. Ve el siguiente ejemplo: # app/config/routing.yml hello: pattern: /hello/{first_name}/{last_name} defaults: { _controller: AcmeHelloBundle:Hello:index, color: green } El controlador para esto puede tomar varios argumentos: public function indexAction($first_name, $last_name, $color) { // ... }
  8. 8. ● El orden de los argumentos del controlador no tiene importancia ● Cada argumento requerido del controlador debe coincidir con un parámetro de enrutado ● No todos los parámetros de enrutado deben ser argumentos en tu controlador public function indexAction($last_name, $color, $first_name) { // ... } public function indexAction($first_name, $last_name, $color, $foo) { // ... } public function indexAction($first_name, $color) { // ... }
  9. 9. La Petición como argumento para el controlador Para mayor comodidad, también puedes hacer que Symfony pase el objeto Petición como un argumento a tu controlador. Esto es conveniente especialmente cuando trabajas con formularios, por ejemplo: use SymfonyComponentHttpFoundationRequest; public function updateAction(Request $request) { $form = $this->createForm(...); $form->bind($request); // ... }
  10. 10. La clase base del controlador Para mayor comodidad, Symfony2 viene con una clase Controller base, que te ayuda en algunas de las tareas más comunes del Controlador y proporciona acceso a cualquier recurso que tu clase controlador pueda necesitar. Al extender esta clase Controlador, puedes tomar ventaja de varios métodos ayudantes. Agrega la instrucción use en lo alto de la clase Controlador y luego modifica HelloController para extenderla: // src/Acme/HelloBundle/Controller/HelloController.php namespace AcmeHelloBundleController; use SymfonyBundleFrameworkBundleControllerController; use SymfonyComponentHttpFoundationResponse; class HelloController extends Controller { public function indexAction($name) { return new Response('<html><body>Hello '.$name.'!</body></html>'); } }
  11. 11. Tareas comunes del controlador A pesar de que un controlador puede hacer prácticamente cualquier cosa, la mayoría de los controladores se encargarán de las mismas tareas básicas una y otra vez. Estas tareas, tal como redirigir, procesar plantillas y acceder a servicios básicos, son muy fáciles de manejar en Symfony2. 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. Por omisión, el método redirect() produce una redirección 302 (temporal). Para realizar una redirección 301 (permanente), modifica el segundo argumento: public function indexAction() { return $this->redirect($this->generateUrl('homepage'), 301); }
  12. 12. Reenviando Además, fácilmente puedes redirigir internamente hacia a otro controlador con el método forward(). En lugar de redirigir el navegador del usuario, este hace una subpetición interna, y llama el controlador especificado. El método forward() regresa el objeto Respuesta, el cual es devuelto desde el controlador: public function indexAction($name) { $response = $this->forward('AcmeHelloBundle:Hello:fancy', array( 'name' => $name, 'color' => 'green' )); // ... adicionalmente modifica la respuesta o la devuelve // directamente return $response; } public function fancyAction($name, $color) { // ... crea y devuelve un objeto Response }
  13. 13. Procesando plantillas Aunque no es un requisito, la mayoría de los controladores en última instancia, reproducen una plantilla que es responsable de generar el código HTML (u otro formato) para el controlador. El método renderView() procesa una plantilla y devuelve su contenido. Puedes usar el contenido de la plantilla para crear un objeto Respuesta: $content = $this->renderView( 'AcmeHelloBundle:Hello:index.html.twig', array('name' => $name) ); return new Response($content); Incluso puedes hacerlo en un solo paso con el método render(), el cual devuelve un objeto Respuesta con el contenido de la plantilla: return $this->render( 'AcmeHelloBundle:Hello:index.html.twig', array('name' => $name) );
  14. 14. 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(). Aquí hay varios servicios comunes que puedes necesitar: $request = $this->getRequest(); $templating = $this->get('templating'); $router = $this->get('router'); $mailer = $this->get('mailer'); Hay un sinnúmero de servicios disponibles y te animamos a definir tus propios servicios. Para listar todos los servicios disponibles, utiliza la orden container:debug de la consola: $ php app/console container:debug
  15. 15. Gestionando errores y páginas 404 Cuando no se encuentra algo, debes jugar bien con el protocolo HTTP y devolver una respuesta 404. Para ello, debes lanzar un tipo de excepción especial. Si estás extendiendo la clase base del controlador, haz lo siguiente: public function indexAction() { // recupera el objeto desde la base de datos $product = ...; if (!$product) { throw $this->createNotFoundException('The product does not exist'); } return $this->render(...); } El método createNotFoundException() crea un objeto NotFoundHttpException especial, que en última instancia, desencadena una respuesta HTTP 404 en el interior de Symfony.
  16. 16. El método createNotFoundException() crea un objeto NotFoundHttpException especial, que en última instancia, desencadena una respuesta HTTP 404 en el interior de Symfony. Por supuesto, estás en libertad de lanzar cualquier clase de Excepción en tu controlador —Symfony2 automáticamente devolverá una respuesta HTTP con código 500. throw new Exception('Something went wrong!'); En todos los casos, el usuario final ve una página de error estilizada y a los desarrolladores se les muestra una página de depuración de error completa (cuando visualizas la página en modo de depuración).
  17. 17. Gestionando la sesión Symfony2 proporciona un agradable objeto sesión que puedes utilizar para almacenar información sobre el usuario (ya sea una persona real usando un navegador, un robot o un servicio web) entre las peticiones. De manera predeterminada, Symfony2 almacena los atributos de una cookie usando las sesiones nativas de PHP. Almacenar y recuperar información de la sesión se puede conseguir fácilmente desde cualquier controlador: $session = $this->getRequest()->getSession(); // guarda un atributo para reutilizarlo durante una // posterior petición del usuario $session->set('foo', 'bar'); // en otro controlador por otra petición $foo = $session->get('foo'); // usa un valor predefinido si la clave no existe $filters = $session->set('filters', array()); Estos atributos se mantendrán en el usuario por el resto de esa sesión.
  18. 18. Mensajes flash También puedes almacenar pequeños mensajes que se pueden guardar en la sesión del usuario para exactamente una petición adicional. Esto es útil cuando procesas un formulario: deseas redirigir y proporcionar un mensaje especial que aparezca en la siguiente petición. Este tipo de mensajes se conocen como mensajes «flash». Por ejemplo, imagina que estás procesando el envío de un formulario: public function updateAction() { $form = $this->createForm(...); $form->bind($this->getRequest()); if ($form->isValid()) { // hace algún tipo de procesamiento $this->get('session')->getFlashBag()->add('notice', 'Your changes were saved!'); return $this->redirect($this->generateUrl(...)); } return $this->render(...);
  19. 19. En la siguiente acción de la plantilla, podrías utilizar el siguiente código para reproducir el mensaje de aviso: Twig: PHP: {% for flashMessage in app.session.flashbag.get('notice') %} <div class="flash-notice"> {{ flashMessage }} </div> {% endfor %} <?php foreach ($view['session']->getFlash('notice') as $message): ?> <div class="flash-notice"> <?php echo "<div class='flash-error'>$message</div>" ?> </div> <?php endforeach; ?>
  20. 20. El objeto Respuesta El único requisito para un controlador es que devuelva un objeto Respuesta. La clase SymfonyComponentHttpFoundationResponse es una abstracción PHP en torno a la respuesta HTTP —el mensaje de texto, relleno con cabeceras HTTP y el contenido que se envía de vuelta al cliente: // crea una simple respuesta con un código de estado 200 (el predeterminado) $response = new Response('Hello '.$name, 200); // crea una respuesta JSON con código de estado 200 $response = new Response(json_encode(array('name' => $name))); $response->headers->set('Content-Type', 'application/json');
  21. 21. El objeto Petición Además de los valores de los marcadores de posición de enrutado, el controlador también tiene acceso al objeto Petición al extender la clase base Controlador: $request = $this->getRequest(); $request->isXmlHttpRequest(); // ¿es una petición Ajax? $request->getPreferredLanguage(array('en', 'fr')); $request->query->get('page'); // obtiene un parámetro $_GET $request->request->get('page'); // obtiene un parámetro $_POST Al igual que el objeto Respuesta, las cabeceras de la petición se almacenan en un objeto HeaderBag y son fácilmente accesibles.
  22. 22. Estructura de directorios: La estructura de directorios en Symfony2 es bastante flexible: app: La configuración de aplicación src: El código PHP del proyecto. vendor: Dependencia de tercero web: directorio raíz del proyecto El directorio web/ Es donde van todo los archivos estáticos como por ejemplo las imágenes, estilos y código javascript. También es donde está el controlador frontal.
  23. 23. 1 2 3 4 5 6 7 8 9 // web/app.php require_once __DIR__.'/../app/bootstrap.php.cache'; require_once __DIR__.'/../app/AppKernel.php'; use SymfonyComponentHttpFoundationRequest; $kernel = new AppKernel('prod', false); $kernel->loadClassCache(); $kernel->handle(Request::createFromGlobals())->send(); El núcleo requiere en primer lugar el archivo bootstrap.php. cache, el cual arranca la plataforma y registra el cargador automático. Al igual que cualquier controlador frontal, app.php utiliza una clase del núcleo,AppKernel, para arrancar la aplicación.
  24. 24. El directorio app/ La clase AppKernel es el punto de entrada principal para la configuración de la aplicación y, como tal, se almacena en el directorio app/. Esta clase debe implementar dos métodos: ● registerBundles() debe devolver un arreglo de todos los paquetes necesarios para ejecutar la aplicación; ● registerContainerConfiguration() carga la configuración de la aplicación (más sobre esto más adelante). La autocarga es manejada automáticamente vía Composer, Si necesitamos más flexibilidad, podemos extender el autocargador en el archivo app/autoload.php. Todas las dependencias están almacenadas bajo el directorio vendor/, pero esto sólo es una convención. Las podemos almacenar en cualquier lugar, globalmente en tu servidor o localmente en tus proyectos.
  25. 25. Comprendiendo el sistema de paquetes(Bundles) Un paquete es un poco como un complemento en otros programas. Así que ¿por qué se llama paquete y no complemento? Esto se debe a que en Symfony2 todo es un paquete, desde las características del núcleo de la plataforma hasta el código que escribes para tu aplicación. Esto proporciona la flexibilidad para utilizar las características preconstruidas envasadas en paquetes de terceros o para distribuir tus propios paquetes. Además, facilita la selección y elección de las características por habilitar en tu aplicación y optimizarlas en la forma que desees. Y al final del día, el código de tu aplicación es tan importante como el mismo núcleo de la plataforma.
  26. 26. Registrando un paquete Una aplicación se compone de paquetes tal como está definido en el método registerBundles() de la clase AppKernel. Cada paquete vive en un directorio que contiene una única clase Paquete que lo describe: // app/AppKernel.php public function registerBundles() { $bundles = array( new SymfonyBundleFrameworkBundleFrameworkBundle(), new SymfonyBundleSecurityBundleSecurityBundle(), new SymfonyBundleTwigBundleTwigBundle(), new SymfonyBundleMonologBundleMonologBundle(), new SymfonyBundleSwiftmailerBundleSwiftmailerBundle(), new SymfonyBundleDoctrineBundleDoctrineBundle(), new SymfonyBundleAsseticBundleAsseticBundle(), new SensioBundleFrameworkExtraBundleSensioFrameworkExtraBundle(), new JMSSecurityExtraBundleJMSSecurityExtraBundle(), ); if (in_array($this->getEnvironment(), array('dev', 'test'))) { $bundles[] = new AcmeDemoBundleAcmeDemoBundle(); $bundles[] = new SymfonyBundleWebProfilerBundleWebProfilerBundle(); $bundles[] = new SensioBundleDistributionBundleSensioDistributionBundle(); $bundles[] = new SensioBundleGeneratorBundleSensioGeneratorBundle(); } return $bundles; }
  27. 27. Extendiendo un paquete Además de ser una buena manera de organizar y configurar tu código, un paquete puede extender otro paquete. La herencia de paquetes te permite sustituir cualquier paquete existente con el fin de personalizar sus controladores, plantillas, o cualquiera de sus archivos. Aquí es donde son útiles los nombres lógicos (por ejemplo, @AcmeDemoBundle/Controller/SecuredController.php): estos abstraen en dónde se almacena realmente el recurso.
  28. 28. Nombres lógicos de archivo Cuando quieras hacer referencia a un archivo de un paquete, utiliza esta notación: @NOMBRE_PAQUETE/ruta/al/archivo; Symfony2 resolverá @NOMBRE_PAQUETE a la ruta real del paquete. Por ejemplo, la ruta lógica@AcmeDemoBundle/Controller/DemoController.php se convierte en src/Acme/DemoBundle/Controller/DemoController.php, ya que Symfony conoce la ubicación del AcmeDemoBundle. Nombres lógicos de Controlador Para los controladores, necesitas hacer referencia a los nombres de método usando el formato NOMBRE_PAQUETE:NOMBRE_CONTROLADOR:NOMBRE_ACCIÓN. Por ejemplo,AcmeDemoBundle:Welcome:index representa al método indexAction de la clase AcmeDemoBundleControllerWelcomeController. Nombres lógicos de plantilla Para las plantillas, el nombre lógico AcmeDemoBundle:Welcome:index.html.twig se convierte en la ruta del archivosrc/Acme/DemoBundle/Resources/views/Welcome/index. html.twig. Incluso las plantillas son más interesantes cuando te das cuenta que no es necesario almacenarlas en el sistema de archivos. Puedes guardarlas fácilmente en una tabla de la base de datos, por ejemplo.
  29. 29. Extendiendo paquetes Si sigues estas convenciones, entonces puedes utilizar herencia de paquetes para «redefinir» archivos, controladores o plantillas. Por ejemplo, puedes crear un paquete — AcmeNewBundle— y especificar que este sustituye a AcmeDemoBundle. Cuando Symfony carga el controlador AcmeDemoBundle:Welcome:index, primero busca la clase WelcomeController en AcmeNewBundle y luego mirará en AcmeDemoBundle. Esto significa que, un paquete puede redefinir casi cualquier parte de otro paquete. Vendors Lo más probable es que la aplicación dependa de bibliotecas de terceros. Estas se deberían guardar en el directorio vendor/. Este directorio ya contiene las bibliotecas Symfony2, la biblioteca SwiftMailer, el ORM de Doctrine, el sistema de plantillas Twig y algunas otras bibliotecas y paquetes de terceros. Comprendiendo la caché y los registros Symfony2 probablemente es una de las plataformas más rápidas hoy día. Pero ¿cómo puede ser tan rápida si analiza e interpreta decenas de archivos YAML y XML por cada petición? La velocidad, en parte, se debe a su sistema de caché. La configuración de la aplicación sólo se analiza en la primer petición y luego se compila hasta código PHP simple y se guarda en el directorio app/cache/. En el entorno de desarrollo, Symfony2 es lo suficientemente inteligente como para vaciar la caché cuando cambias un archivo. Pero en el entorno de producción, es tu responsabilidad borrar la caché cuando actualizas o cambias tu código o configuración. Al desarrollar una aplicación web, las cosas pueden salir mal de muchas formas. Los archivos de registro en el directorio app/logs/ dicen todo acerca de las peticiones y ayudan a solucionar rápidamente el problema.
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×