Silex
  desarrollo web ágil y
  profesional con PHP

BILBOSTACK          JAVIER EGUILUZ
26 ENERO 2013
Gracias a la organización.



Asier   Fran     Ibon    Vicenç
Agenda
 1. Introducción
 2. Programando aplicaciones
 3. DEMO
 4. Buenas prácticas
 5. Puntos débiles
Introducción
¿Por qué?
En el mundo de los negocios...
1. Rápido
2. Barato
3. Bueno
En el mundo de los negocios...
1. Rápido              ELIGE DOS

2. Barato
3. Bueno
En el mundo de la programación...
1. Bien hecho
2. Terminado a tiempo
3. Barato
En el mundo de la programación...
1. Bien hecho     ELIGE UNA

2. Terminado a tiempo
3. Barato
En el mundo de la programación...
✔ Bien
1.     hecho
✔ Terminado a tiempo
2.
✔ Barato
3.
   Con Silex puedes
   tenerlo todo
¡no tengo
¡quiero hacerlo bien!    tiempo!
¿Qué es
 Silex?
Foto: Wikipedia
Curiosity (2012)




                  Sojourner (2007)
Foto: Wikipedia
Sojourner   Curiosity
                (2007)      (2012)

Masa            11 kg      900 kg
Coste ($)      150 M      1.800 M
Memoria RAM     64 KB      256 MB
CPU             2 MHz     200 MHz
Es importante tener en cuenta que...
• El grande jamás podrá ser tan ágil
  como el pequeño.
• El pequeño jamás podrá competir
  en potencia y funcionalidad con el
  grande.
Silex
The PHP micro-framework
based on the Symfony2
Components

                           el logo
                          de Silex
los dos son frameworks y usan los mismos componentes, pero...
...Symfony es un framework muy grande y Silex es un framework muy pequeño
Silex   Symfony2
Peso               5 MB      8 MB
Archivos           3.366    6.578
Nivel dificultad

Flexibilidad
Los creadores de Silex




Igor Wiedler     Fabien Potencier
@igorw           @fabpot
+ fácil     + calidad
- calidad   - facil
+ fácil     + calidad
- calidad   - facil
Programando
 aplicaciones
Funciones anónimas
         y closures
Función normal
function suma($a, $b) {
  return $a + $b;
}
Función anónima
function ($a, $b) {
  return $a + $b;
}
Usando una función anónima
$app->get('...', function ($a, $b) {
   return $a + $b;
});
Closure
$a = 3;
function ($b) {
  return $a + $b;
}
Closure
$a = 3;             NO FUNCIONA
function ($b) {
  return $a + $b;
}
Closure
$a = 3;
function ($b) use ($a) {
  return $a + $b;
}
El código más común de Silex
$app->get('...', function ($var) use ($app) {
   // ...
});
El primer
 ejemplo
Hola
mundo.
http://bilbostack.com/hola
Hola Mundo en Silex
require_once __DIR__.'/../vendor/autoload.php';

$app = new SilexApplication();

$app->get('/hola', function() {
   return 'Hola mundo';
});

$app->run();
Cargar clases automáticamente
require_once __DIR__.'/../vendor/autoload.php';

$app = new SilexApplication();

$app->get('/hola', function() {
   return 'Hola mundo';
});

$app->run();
Crear la aplicación Silex
require_once __DIR__.'/../vendor/autoload.php';

$app = new SilexApplication();

$app->get('/hola', function() {
   return 'Hola mundo';
});

$app->run();
Ejecutar código para una URL
require_once __DIR__.'/../vendor/autoload.php';

$app = new SilexApplication();

$app->get('/hola', function() {
   return 'Hola mundo';
});

$app->run();
Arrancar la aplicación
require_once __DIR__.'/../vendor/autoload.php';

$app = new SilexApplication();

$app->get('/hola', function() {
   return 'Hola mundo';
});

$app->run();
Hola Mundo en Silex
require_once __DIR__.'/../vendor/autoload.php';

$app = new SilexApplication();

$app->get('/hola', function() {
   return 'Hola mundo';
});

$app->run();
Sinatra / Ruby

require 'sinatra'

get '/hola' do
 "Hola mundo."
end
node.js / JavaScript

var http = require('http');

http.createServer(function (request, response) {
   response.writeHead(
      200, { 'Content-Type': 'text/plain' }
   );
   response.end('Hola mundon');
}).listen(80);
Un ejemplo
       real
Silex, desarrollo web ágil y profesional con PHP
Fo
                     rk
                          m
                           eo
                              n
github.com/                       Gi
                                    tH
                                      ub

javiereguiluz/bilbostack
Enrutamiento
Ruta de la portada
$app->get('/', function () use ($app) {
   // ...
});
Ruta básica
$app->get('/agenda', function () use ($app) {
   // ...
});
Ruta con partes variables
$app->get('/speakers/{slug}', function ()
                              use ($app) {
   // ...
});
Ruta con partes variables
$app->get('/speakers/{slug}', function ()
                              use ($app) {
   // ...
});
Ruta con partes variables
$app->get('/speakers/{slug}', function ()
                              use ($app) {
   // ...
});

/speakers/pablo-garaizar
/speakers/carlos-sanchez
/speakers/esto-esta-mal
Otros métodos HTTP
$app->post('/registro', function () use ($app) {
   // ...
});
Otros métodos HTTP
$app->post('/registro', function () use ($app) {
   // ...
});

$app->put( );
$app->delete( );
Ruta para todos los métodos HTTP
$app->match('/registro', function () use ($app) {
   // ...
});
Ruta para algunos métodos HTTP
$app->match('/registro', function () use ($app) {
   // ...
})
->method('GET|POST');
Rutas con variables
$app->get('/speakers/{slug}', function ($slug) {
   // ...
});
Rutas con variables
$app->get('/speakers/{track}/{slug}',
         function ($track, $slug) use ($app) {
   // ...
});
Variables especiales
use SymfonyComponentHttpFoundationRequest;

$app->get('/speakers/{slug}',
         function (Request $request, $slug) {
   // ...
});
Variables especiales
use SymfonyComponentHttpFoundationRequest;

$app->get('/speakers/{slug}',
         function (Request $request, $slug) {
   // ...
});
Variables especiales
use SymfonyComponentHttpFoundationRequest;

$app->get('/speakers/{slug}',
         function (Request $request, $slug) {
   // ...
});

$request->server->get('HTTP_USER_AGENT')
$request->get('slug')
Modificando las variables de la ruta
$app->get('/schedule/{slug}',
         function ($slug) use ($app) {
   // ...
})->convert('slug', function ($slug) {
   return strtolower($slug);
});
Modificando las variables de la ruta
$app->get('/schedule/{slug}',
         function ($slug) use ($app) {
   // ...
})->convert('slug', function ($slug) {
   return str_replace('-', '_', $slug);
});
Restringiendo las variables de la ruta
$app->get('/schedule/{track}', function ($track)
{
  // ...
})->assert('track', 'd+');
Restringiendo las variables de la ruta
$app->get('/schedule/{track}', function ($track)
{
  // ...
})->assert('track', 'trackd+');
Restringiendo las variables de la ruta
$app->get('/schedule/{track}', function ($track)
{
  // ...
})->assert('track', '1|2');
Valores por defecto
$app->get('/schedule/{track}', function ($track)
{
  // ...
})->value('track', '1');
Valores por defecto
$app->get('/schedule/{track}', function ($track)
{
  // ...
})->value('track', '1');

/schedule
/schedule/1
Rutas con nombre
$app->get('/', function () use ($app) {
  // ...
})->bind('portada');
Controladores
Controlador básico
$app->get('/donde-comer', function ()
                             use ($app) {
   return $app['twig']->render('comer.twig');
})
->bind('comer');
Controlador típico
$app->get('/', function () use ($app) {
  $ponentes = $app['ponentes'];

  return $app['twig']->render('portada.twig',
         array('ponentes' => $ponentes)
  );
})->bind('portada');
Controlador típico
$app->get('/', function () use ($app) {
  $ponentes = $app['ponentes'];

  return $app['twig']->render('portada.twig',
         array('ponentes' => $ponentes)
  );
})->bind('portada');
Gestión de errores
$app->get('/speakers/{slug}',
      function ($slug) use ($app) {
  if (...) {
      $app->abort(404, "No existe el ponente.");
  }

  // ...

  return $app['twig']->render('ponente.twig',...);
})->bind('ponente');
Gestión de errores
$app->get('/speakers/{slug}',
      function ($slug) use ($app) {
  if (...) {
      $app->abort(404, "No existe el ponente.");
  }

  // ...

  return $app['twig']->render('ponente.twig',...);
})->bind('ponente');
Controlador especial para errores
$app->error(function (Exception $e, $code)
            use ($app) {

  // ...

});
Controlador especial para errores
$app->error(function (Exception $e, $code)
            use ($app) {

  // ...

});
Esqueleto de una aplicación Silex
$app->get('/', ...)->bind('portada');

$app->get('/agenda', ...)->bind('agenda');

$app->get('/speakers/{slug}', ...)
->bind('ponente');

$app->get('/schedule/{slug}', ...)
->bind('ponencia');
1 aplicación = 1 archivo
$app->get('/', ...)->bind('portada');

$app->get('/agenda', ...)-
>bind('agenda');

$app->get('/speakers/{slug}', ...)
->bind('ponente');

$app->get('/schedule/{slug}', ...)
->bind('ponencia');




                 controllers.php
1 aplicación = 1 archivo

                                        EL ORDEN
$app->get('/', ...)->bind('portada');

$app->get('/agenda', ...)-
>bind('agenda');                         IMPORTA
$app->get('/speakers/{slug}', ...)
->bind('ponente');

$app->get('/schedule/{slug}', ...)
->bind('ponencia');




                 controllers.php
Middlewares
     (filtros)
Petición HTTP           Objeto Request



                    Silex



                            Tu aplicación




Página HTML         Silex
                            Objeto Response
Petición HTTP           Objeto Request

                                     !
                    Silex



                            Tu aplicación

         !                            !

Página HTML         Silex
                            Objeto Response
Filtro before
$app->before(function (Request $request) {
   // ...
});
Secuencia de ejecución
• Buscar la ruta que pide el usuario.
• Comprobar la seguridad.
• Ejecutar filtro before()
• Ejecutar controlador de la ruta
Ejemplo de filtro before
$app->before(function (Request $request) {
   if (...) {
       return new RedirectResponse('/login');
   }
});
Filtro after
$app->after(function (Request $request,
                      Response $response) {
   // ...
});
Secuencia de ejecución
• Buscar la ruta que pide el usuario.
• Comprobar la seguridad.
• Ejecutar filtro before( )
• Ejecutar controlador de la ruta.
• Ejecutar filtro after( )
• Enviar respuesta al usuario.
Ejemplo de filtro after
$app->after(function (Request $request) {
   log('...');
});
Ejemplo de filtro after
$app->after(function (Request $request) {
   log('...');
});

                 ¿Dónde está mi
                   respuesta?
Filtro finish
$app->finish(function (Request $request,
                       Response $response) {
   // ...
});
Cada ruta con su filtro
$app->get('/', ...)->bind('portada')->before(...);

$app->get('/agenda', ...)->bind('agenda')
->before(...)->after(...);

$app->get('/speakers/{slug}', ...)
->bind('ponente')->before(...);

$app->get('/schedule/{slug}', ...)
->bind('ponencia')->before(...);
Proveedores de
      servicios
Bases de datos


           Formularios

Núcleo     Plantillas

de Silex   Caché HTTP


           Envío de emails

             proveedores
Bases de datos


                        Formularios

Núcleo     Plantillas

de Silex                Caché HTTP


                        Envío de emails

                          proveedores
Bases de datos


           Formularios

Núcleo                   Plantillas

de Silex                 Caché HTTP


                      Envío de emails

                            proveedores
Bases de datos


           Formularios

Núcleo     Plantillas

de Silex   Caché HTTP


           Envío de emails
Bases de datos   Serializador   Seguridad


Formularios      Logger         Sesiones


Validación       Emails         Plantillas


Caché HTTP       URL
Usar formularios de Symfony2
use SilexProviderFormServiceProvider;

// ...

$app->register(new FormServiceProvider());
Acceder a BBDD con Doctrine2
use SilexProviderDoctrineServiceProvider;

// ...

$app->register(new DoctrineServiceProvider());
Utilizar las plantillas de Twig
use SilexProviderTwigServiceProvider;

// ...

$app->register(new TwigServiceProvider(), array(
  'twig.path' => array(__DIR__.'/../templates'),
  'twig.options' => array('...'),
));
DEMO
github.com/javiereguiluz/bilbostack




                                                ub
                                          G itH
                                   e on
                                k m
                            F or
Instalación
Descargar archivo comprimido

   silex.sensiolabs.org
Descargar archivo comprimido
Descargar archivo comprimido
Descargar archivo comprimido
Instalación via composer.json
{
  "require": {
     "silex/silex": "1.0.*"
  },
  "minimum-stability": "dev"
}
Instalación via composer.json
{
  "require": {
     "fabpot/silex-skeleton": "*"
  },
  "minimum-stability": "dev"
}
Instalación recomendada
$ composer
  create-project
  fabpot/silex-skeleton
  --stability=dev
Silex, desarrollo web ágil y profesional con PHP
Silex, desarrollo web ágil y profesional con PHP
Silex, desarrollo web ágil y profesional con PHP
Silex, desarrollo web ágil y profesional con PHP
Silex, desarrollo web ágil y profesional con PHP
web/        src/      src/
index.php   app.php   controllers.php
web/        src/      src/
index.php   app.php   controllers.php




No tocar
web/        src/        src/
index.php   app.php     controllers.php




No tocar     Activas
            servicios
web/        src/        src/
index.php   app.php     controllers.php




No tocar     Activas       $app
            servicios   ->get('/', ...});
Buenas
prácticas
Organizando
los controladores
$app->get('/', ...);

                         // ...


                                  controllers.php

$app->get('/', ...);     $app->get('/', ...);



              blog.php              backend.php
Importando controladores
$app->mount('/blog', include 'blog.php');
$app->mount('/admin', include 'backend.php');
Importando controladores
$app->mount('/blog', include 'blog.php');
$app->mount('/admin', include 'backend.php');
Importando controladores
$app->mount('/blog', include 'blog.php');
$app->mount('/admin', include 'backend.php');


PORTADA: /
PORTADA DE BLOG: /blog/
PORTADA DE BACKEND: /admin/
1 aplicación = 1 archivo
$app->get('/', ...)->bind('portada');

$app->get('/agenda', ...)-
>bind('agenda');

$app->get('/speakers/{slug}', ...)
->bind('ponente');

$app->get('/schedule/{slug}', ...)
->bind('ponencia');




                 controllers.php
1 aplicación pequeña = 1 archivo
$app->get('/', ...)->bind('portada');

$app->get('/agenda', ...)-
>bind('agenda');

$app->get('/speakers/{slug}', ...)
->bind('ponente');

$app->get('/schedule/{slug}', ...)
->bind('ponencia');




                 controllers.php
1 aplicación mediana = N archivos
$app->get('/', ...)->bind('portada');   $app->get('/', ...);

$app->get('/agenda', ...)-              $app->get('/ver', ...);
>bind('agenda');
                                        $app->get('/listar', ...);
$app->get('/speakers/{slug}', ...)
->bind('ponente');
                                                                     blog.php
$app->get('/schedule/{slug}', ...)
->bind('ponencia');



                                        $app->get('/', ...);




                 controllers.php                               backend.php
Escalando una
aplicación Silex
Controladores como clases
namespace IgorwShopController;

use SilexApplication;
use SymfonyComponentHttpFoundationRequest;

class ShopController
{
   public function indexAction(Request $request, Application $app)
   {
     ...
   }
}
Controladores como clases
$app->get('/', controller('shop/index'));
$app->match('/login', controller('shop/login'));
$app->get('/product', controller('shop/
product'));
http://igor.io/2012/11/09/scaling-silex.html
Puntos
débiles
i18n   Depuración

ORM    Documentación

ESI
i18n (internacionalización)
• Fácil traducir contenidos
  {{ "Hola Mundo"|trans }}
• No es cómodo traducir rutas y
  contenidos de la base de datos.
ORM
• No hay soporte oficial del ORM
 completo (Doctrine2).
• No hay ORM alternativos ligeros.
• Si tu aplicación necesita un ORM,
 puede ser demasiado grande para
 Silex.
Depuración
// activar el modo debug
$app['debug'] = true;

// activar el log
use SilexProviderMonologServiceProvider;

$app->register(new MonologServiceProvider(),
array(
    'monolog.logfile' => __DIR__.'/../logs/dev.log',
));
Mensajes de error
Silex, desarrollo web ágil y profesional con PHP
ESI
• Silex incluye soporte de ESI.
• Su uso es bastante incómodo
  (comparado con Symfony2).
Documentación
• Todas las características de Silex
  están documentadas.
• No es tan abundante como la de
  Symfony2.
Documentación
• Oficial
  silex.sensiolabs.org/documentation
• Traducción
  librosweb.es/silex
Conclusiones
Conclusiones
• Silex es un microframework, pero no es
  un juguete.
Conclusiones
• Silex es un microframework, pero no es
  un juguete.
• Silex sirve para cualquier aplicación
  web que no sea enorme.
Conclusiones
• Silex es un microframework, pero no es
  un juguete.
• Silex sirve para cualquier aplicación
  web que no sea enorme.
• Silex reduce a “horas” el tiempo de
  desarrollo de aplicaciones enteras.
Conclusiones
• Silex es un microframework, pero no es
  un juguete.
• Silex sirve para cualquier aplicación
  web que no sea enorme.
• Silex reduce a “horas” el tiempo de
  desarrollo de aplicaciones enteras.
• Silex combina la agilidad de PHP con la
  profesionalidad de Symfony.
GRACIAS.
Contacto
         • javier.eguiluz@gmail.com
         • twitter.com/javiereguiluz
         • github.com/javiereguiluz
         • linkedin.com/in/javiereguiluz



domingo, 27 de enero de 13

Más contenido relacionado

PDF
Backend (sf2Vigo)
PDF
Desymfony 2011 - Tutorial #5: Backend
PDF
Desymfony 2011 - Tutorial #1: Instalacion y primeros pasos
PDF
Cómo domar SonataAdminBundle
PDF
Desymfony 2011 - Introducción a Symfony2
PDF
deSymfony 2013 - Creando aplicaciones web desde otro ángulo con Symfony y A...
PDF
Symfony2, Jornadas Symfony
PDF
Desarrollo código mantenible en WordPress utilizando Symfony
Backend (sf2Vigo)
Desymfony 2011 - Tutorial #5: Backend
Desymfony 2011 - Tutorial #1: Instalacion y primeros pasos
Cómo domar SonataAdminBundle
Desymfony 2011 - Introducción a Symfony2
deSymfony 2013 - Creando aplicaciones web desde otro ángulo con Symfony y A...
Symfony2, Jornadas Symfony
Desarrollo código mantenible en WordPress utilizando Symfony

La actualidad más candente (20)

PDF
Introducción al microframework PHP Silex - Sergio Gómez - Betabeers Córdoba 0...
PDF
WordCamp Cantabria - Código mantenible con WordPress
PDF
RabbitMQ y Symfony
PDF
Slides components en
PDF
Doctrine2 sf2Vigo
RTF
Wp config.php
PDF
Curso Drupal. Creacion de modulos en Drupal
PDF
PHP Tema 2 - Lenguaje PHP básico
PDF
Api De Google Calendar
PDF
Symfony en Drupal 8 - DrupalCamp Spain
KEY
Introducción a Flask
KEY
Introducción a DJango
PDF
Integrando React.js en aplicaciones Symfony (deSymfony 2016)
PDF
Ejemplos de php_mysql
DOC
Php
PPSX
Introducción a los hooks
PDF
Materiales del curso de Symfony2
ODP
Desarrollo Web Ágil con Symfony, Bootstrap y Angular
DOCX
Php excel
DOCX
Programa que almacena en una base de datos las características de un carro co...
Introducción al microframework PHP Silex - Sergio Gómez - Betabeers Córdoba 0...
WordCamp Cantabria - Código mantenible con WordPress
RabbitMQ y Symfony
Slides components en
Doctrine2 sf2Vigo
Wp config.php
Curso Drupal. Creacion de modulos en Drupal
PHP Tema 2 - Lenguaje PHP básico
Api De Google Calendar
Symfony en Drupal 8 - DrupalCamp Spain
Introducción a Flask
Introducción a DJango
Integrando React.js en aplicaciones Symfony (deSymfony 2016)
Ejemplos de php_mysql
Php
Introducción a los hooks
Materiales del curso de Symfony2
Desarrollo Web Ágil con Symfony, Bootstrap y Angular
Php excel
Programa que almacena en una base de datos las características de un carro co...
Publicidad

Destacado (20)

PDF
Silex para aplicaciones web MVC
PDF
Introducción a Silex. Aprendiendo a hacer las cosas bien en PHP
PPTX
Introducción a Silex
PDF
Create - Decoupled CMS interface
PPS
Parque De Agua Web - Propuesta
DOCX
Propuesta diseño web
PPTX
Propuesta web
PPT
Propuesta web 2.0 greatest (f)
PDF
Febrero 2009 - Presentación PFC AGritos!
PDF
Presentación Framework CodeIgniter
PPT
DESARROLLO RAPIDO DE APLICACIONES WEB
PDF
Iniciación PHP 5. Programación Web
PDF
MODELO VISTA CONTROLADOR EN PHP
PPT
Curso php y_my_sql
PDF
Iniciación PHP 5. Introducción
ODP
Iniciación PHP 5. Programación Orientada a Objetos
DOC
Propuesta Portal Web
PDF
Twig avanzado (sf2Vigo)
PDF
Iniciación PHP 5. Ejercicios
Silex para aplicaciones web MVC
Introducción a Silex. Aprendiendo a hacer las cosas bien en PHP
Introducción a Silex
Create - Decoupled CMS interface
Parque De Agua Web - Propuesta
Propuesta diseño web
Propuesta web
Propuesta web 2.0 greatest (f)
Febrero 2009 - Presentación PFC AGritos!
Presentación Framework CodeIgniter
DESARROLLO RAPIDO DE APLICACIONES WEB
Iniciación PHP 5. Programación Web
MODELO VISTA CONTROLADOR EN PHP
Curso php y_my_sql
Iniciación PHP 5. Introducción
Iniciación PHP 5. Programación Orientada a Objetos
Propuesta Portal Web
Twig avanzado (sf2Vigo)
Iniciación PHP 5. Ejercicios
Publicidad

Similar a Silex, desarrollo web ágil y profesional con PHP (20)

PPTX
Symfony-Community: Introducción a Symfony Framework
ODP
Introducción a Kohana Framework
PPTX
Framework kahana
PDF
Desarrollo rápido de apps web con laravel - DevAcademy
PPTX
Framework Laravel
PDF
Clase 3 instalación y primeros pasos
PDF
Symfony2
PPTX
Funciones en php
PDF
Symfony2 es
PDF
Symfony2 Introducción
PDF
Introducción al framework Symfony
PDF
Groovy&Grails: Cambia la forma de desarrollar tus aplicaciones web
PDF
Cambia la forma de desarrollar tus aplicaciones web con groovy y grails
PDF
Mis primeros pasos con Symfony 2
PPTX
BilboStack - Php en el 2012
PPT
Corp. In. Tec. S.A. - Capacitaciones en Informática - Programación con CodeIg...
PPTX
CRUD básico con Symfony
PDF
Tutorial de cakePHP itst
Symfony-Community: Introducción a Symfony Framework
Introducción a Kohana Framework
Framework kahana
Desarrollo rápido de apps web con laravel - DevAcademy
Framework Laravel
Clase 3 instalación y primeros pasos
Symfony2
Funciones en php
Symfony2 es
Symfony2 Introducción
Introducción al framework Symfony
Groovy&Grails: Cambia la forma de desarrollar tus aplicaciones web
Cambia la forma de desarrollar tus aplicaciones web con groovy y grails
Mis primeros pasos con Symfony 2
BilboStack - Php en el 2012
Corp. In. Tec. S.A. - Capacitaciones en Informática - Programación con CodeIg...
CRUD básico con Symfony
Tutorial de cakePHP itst

Más de Javier Eguiluz (17)

PDF
deSymfony 2017: Symfony 4, Symfony Flex y el futuro de Symfony
PDF
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
PDF
Mastering Twig (DrupalCon Barcelona 2015)
PDF
Symfony tips and tricks
PDF
Twig, el nuevo motor de plantillas de Drupal 8
PDF
Silex al límite
PDF
Twig tips and tricks
PDF
Twig, los mejores trucos y técnicas avanzadas
PDF
Wallpaper Notifier
PDF
Desymfony 2012 - Concurso de diseño
PDF
Desymfony 2011 - Twig
PDF
Curso Symfony - Anexos
PDF
Curso Symfony - Clase 5
PDF
Curso Symfony - Clase 4
PDF
Curso Symfony - Clase 3
PDF
Curso Symfony - Clase 2
PDF
Curso Symfony - Clase 1
deSymfony 2017: Symfony 4, Symfony Flex y el futuro de Symfony
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
Mastering Twig (DrupalCon Barcelona 2015)
Symfony tips and tricks
Twig, el nuevo motor de plantillas de Drupal 8
Silex al límite
Twig tips and tricks
Twig, los mejores trucos y técnicas avanzadas
Wallpaper Notifier
Desymfony 2012 - Concurso de diseño
Desymfony 2011 - Twig
Curso Symfony - Anexos
Curso Symfony - Clase 5
Curso Symfony - Clase 4
Curso Symfony - Clase 3
Curso Symfony - Clase 2
Curso Symfony - Clase 1

Último (20)

PDF
Estrategia de apoyo de tecnología 9-5 Daylin Castaño
PPTX
Del SIEM Tradicional al SOC del Futuro: La Evolución Inteligente
PPTX
LEGALIZACIÓN Y VERIFICACIÓN DE UN APARATO TAXÍMETRO
PDF
EL RESPETO mejororado para aprender .pdf
PDF
Sesión 6 - Seguridad de almacenamiento.pdf
PPTX
1.Introducción a los sistemas de control.pptx
PDF
sol tecnología 2025.pdf........pdf10-7grado
PDF
Sociedad y ética digital en inteligencia artificial
PPTX
Redes neuronales artificiales y como entrenarlas
PDF
Ciberataques, Normativas y Protección: Ayudando a las Entidades Financieras a...
PPTX
VariablesExpresiones.pptx conceptos que puedes usar en c++
PPTX
proceso de la comunicación entre computadoras 21111.pptx
PPTX
en este libro encontrarás la lectura inicial para tus niños
PDF
004-CC2014-Irrigacion Mbb equinos del mundo
PDF
Herramientas-de-Recuperacion-de-Datos.pdf
PDF
conceptosbsicosdeprogramacinpseintlaura.pdf
PDF
Conceptos básicos de programación PseInt laura.pdf
PDF
Más Allá de la Autenticación: Gestión Moderna de Identidad en el sector Finan...
PPTX
Desarrollo Seguro en un mundo multi-stack con Pruebas de Seguridad de Forma A...
DOCX
Conceptos básicos de programación PseInt laura.docx
Estrategia de apoyo de tecnología 9-5 Daylin Castaño
Del SIEM Tradicional al SOC del Futuro: La Evolución Inteligente
LEGALIZACIÓN Y VERIFICACIÓN DE UN APARATO TAXÍMETRO
EL RESPETO mejororado para aprender .pdf
Sesión 6 - Seguridad de almacenamiento.pdf
1.Introducción a los sistemas de control.pptx
sol tecnología 2025.pdf........pdf10-7grado
Sociedad y ética digital en inteligencia artificial
Redes neuronales artificiales y como entrenarlas
Ciberataques, Normativas y Protección: Ayudando a las Entidades Financieras a...
VariablesExpresiones.pptx conceptos que puedes usar en c++
proceso de la comunicación entre computadoras 21111.pptx
en este libro encontrarás la lectura inicial para tus niños
004-CC2014-Irrigacion Mbb equinos del mundo
Herramientas-de-Recuperacion-de-Datos.pdf
conceptosbsicosdeprogramacinpseintlaura.pdf
Conceptos básicos de programación PseInt laura.pdf
Más Allá de la Autenticación: Gestión Moderna de Identidad en el sector Finan...
Desarrollo Seguro en un mundo multi-stack con Pruebas de Seguridad de Forma A...
Conceptos básicos de programación PseInt laura.docx

Silex, desarrollo web ágil y profesional con PHP