SlideShare a Scribd company logo
1 of 192
Frameworks de desarrollo

Symfony
Clase 1

                       Javier Eguíluz
                       javier.eguiluz@gmail.com
Esta obra dispone de una licencia de tipo Creative
Commons Reconocimiento‐No comercial‐ Compartir 
             bajo la misma licencia 3.0 




 Se prohíbe explícitamente el uso de este material en 
        actividades de formación comerciales

http://creativecommons.org/licenses/by‐nc‐sa/3.0/es/
This work is licensed under a Creative Commons
  Attribution‐Noncommercial‐Share Alike 3.0 




    The use of these slides in commercial courses or
            trainings is explicitly prohibited

 http://creativecommons.org/licenses/by‐nc‐sa/3.0/es/
Capítulo 1

Comenzando el 
proyecto
¿Qué es 
Symfony?
Framework para el 
desarrollo de aplicaciones 
      web con PHP
• El más profesional

• El más documentado

• El mejor
PHP      Frameworks
Productividad

Calidad programación

Mantenimiento

Rendimiento aplicación
Curva de aprendizaje 
              de Symfony
aprendizaje




                            tiempo
¿Qué es Jobeet?
diciembre 2008
1    2    3       4     5      6    7


8    9    10      11    12     13   14


15   16   17      18    19     20   21


22   23   24      25    26     27   28


29   30   31
La mejor forma de aprender 
 Symfony 1.2 a través de 24
    tutoriales de 1 hora
Un tutorial
 diferente
• Serio

• Profesional

• Completo
Prerrequisitos
5.2.4
Instalación de 
   Symfony
http://www.symfony‐project.org/installation/1_2




symfony‐1.2.4.tgz
check_configuration.php
$ php lib/vendor/symfony/data/bin/symfony
Preparar el 
 proyecto
frontend   backend
proyecto                jobeet
aplicación




                                 backend
             frontend
$ symfony generate:project jobeet

    apps/            log/
    cache/           plugins/
    config/          test/
    lib/             web/
frontend/
$ symfony                       config/
generate:app
                                lib/
jobeet
‐‐escaping‐strategy=on
                                modules/
‐‐csrf‐secret=UniqueSecret
frontend                        templates/
‐‐escaping‐strategy   XSS
      ‐‐csrf‐secret   CSRF
config/ProjectConfiguration.class.php


require_once dirname(__FILE__).
  '/../lib/vendor/'.
  'symfony/lib/autoload/'.
  'sfCoreAutoload.class.php';
Los entornos
• Entorno de desarrollo (dev)
• Entorno de pruebas
• Entorno intermedio
• Entorno de producción (prod)
Errores en el entorno de desarrollo (dev)
Errores en el entorno de producción (prod)
web/index.php
<?php

require_once(dirname(__FILE__).
  '/../config/ProjectConfiguration.class.php');

$configuration = 
ProjectConfiguration::getApplicationConfiguration(
     'frontend',
     'prod',
     false
);

sfContext::createInstance($configuration)‐>dispatch();
Configurar bien el 
  servidor web
<VirtualHost 127.0.0.1:80>
 ServerName jobeet.localhost
 DocumentRoot quot;/home/sfprojects/jobeet/webquot;
 DirectoryIndex index.php

 <Directory quot;/home/sfprojects/jobeet/webquot;>
   AllowOverride All
   Allow from All
 </Directory>

 Alias /sf /home/sfprojects/jobeet/lib/vendor/symfony/data/web/sf
 <Directory quot;/home/sfprojects/jobeet/lib/vendor/symfony/data/web/sfquot;>
   AllowOverride All
   Allow from All
 </Directory>
</VirtualHost>
/etc/hosts
  c:windowssystem32driversetchosts



127.0.0.1    jobeet.localhost
http://jobeet.localhost/

                           prod
http://jobeet.localhost/frontend_dev.php

                                     dev
Versionado de 
   código
Capítulo 2

El proyecto
La idea del 
 proyecto
Aplicación de software 
libre que permite crear 
sitios web de búsqueda 
       de empleo
características

• Completo y personalizable
• Multilingüe
• AJAX, RSS y API
Los escenarios del 
     proyecto
• administrador (admin)
• usuario (user)
• publicador (poster)
• afiliado (affiliate)
F1
El usuario accede a 
la portada y ve las 
últimas ofertas de 
trabajo activas
F2
El usuario puede 
visualizar todas 
las ofertas de 
trabajo de una 
categoría
F3
El usuario refina el 
listado mediante 
palabras clave
F4
El usuario pincha 
sobre una oferta de 
trabajo para ver 
más información
F5
El usuario publica 
una nueva oferta 
de trabajo
F6
El usuario quiere 
convertirse en un 
afiliado
F7
Un usuario afiliado 
obtiene la lista de 
ofertas de trabajo 
activas
B1
El administrador configura el sitio web

B2
El administrador gestiona las ofertas de 
trabajo
B3
El administrador gestiona los afiliados
Capítulo 3

El modelo de 
datos
El modelo 
relacional
relacional         objetos



             ORM
1. Describir la base de datos
2. Generar las clases PHP
3. Trabajar con objetos en vez 
 de SQL
El formato YAML
YAML
 Formato para serializar datos que 
es fácil de leer por las personas y es 
compatible con todos los lenguajes 
          de programación
$casa = array(
   'familia' => array(
      'apellido' => 'García',
      'padres'   => array('Antonio', 'María'),   
      'hijos'    => array('Jose', 'Manuel')
   ),
   'direccion' => array(
      'numero'       => 34,
      'calle'        => 'Gran Vía',
      'ciudad'       => 'Cualquiera',
      'codigopostal' => '12345'
   )
);
casa:
  familia:
    apellido: García
    padres:
      ‐ Antonio
      ‐ María
    hijos:
      ‐ Jose
      ‐ Manuel
  direccion:
    numero: 34
    calle: Gran Vía
    ciudad: Cualquiera
    codigopostal: quot;12345quot;
casa:
  familia: { apellido: García, padres: [Antonio, 
María], hijos: [Jose, Manuel] }
  direccion: { numero: 34, direccion: Gran Vía, 
ciudad: Cualquiera, codigopostal: quot;12345quot; }
Sintaxis
clave:             clave:
  clave: valor
                     clave: valor
  clave:
    clave: valor
    clave:
                       2 espacios 
       ‐ valor
                       en blanco
       ‐ valor
Arrays normales
clave:
  ‐ valor1
  ‐ valor2
  ‐ valor3

clave:[valor1, valor2, valor3]
Arrays asociativos
clave:
  clave1: valor1
  clave2: valor2
  clave3: valor3
clave: { clave1: valor1, 
clave2: valor2, clave3: valor3}
<?xml version=quot;1.0quot;?>
                                XML                                YAML
<club>
                                          players:
  <players>
                                            Vladimir Kramnik: &kramnik
    <player id=quot;kramnikquot; name=quot;Vladimir
                                              rating: 2700
Kramnikquot; rating=quot;2700quot; status=quot;GMquot; /> 
    <player id=quot;fritzquot; name=quot;Deep             status: GM
Fritzquot; rating=quot;2700quot; status=quot;Computerquot;      Deep Fritz: &fritz
/>                                            rating: 2700
    <player id=quot;mertzquot; name=quot;David 
                                              status: Computer
Mertzquot; rating=quot;1400quot; status=quot;Amateurquot; 
                                            David Mertz: &mertz
/>
                                              rating: 1400
</players>
                                              status: Amateur
<matches>
                                          matches:
  <match>
    <Date>2002‐10‐04</Date>                 ‐
    <White refid=quot;fritzquot; />                   Date: 2002‐10‐04
    <Black refid=quot;kramnikquot; />                 White: *fritz
    <Result>Draw</Result> 
                                              Black: *kramnik
  </match>
                                              Result: Draw
  <match>
                                            ‐
    <Date>2002‐10‐06</Date>
                                              Date: 2002‐10‐06
    <White refid=quot;kramnikquot; />
                                              White: *kramnik
    <Black refid=quot;fritzquot; />
    <Result>White</Result>                    Black: *fritz
  </match>                                    Result: White
</matches>
</club> 
El esquema
config/schema.yml
propel:
  jobeet_category:
    id:   ~
    name: { type: varchar(255), required: true, index: unique }
  jobeet_job:
    id:           ~
    category_id:  { type: integer, foreignTable: jobeet_category, foreignReference: id, required: true }
    type:         { type: varchar(255) }
    company:      { type: varchar(255), required: true }
    logo:         { type: varchar(255) }
    url:          { type: varchar(255) }
    position:     { type: varchar(255), required: true }
    location:     { type: varchar(255), required: true }
    description:  { type: longvarchar, required: true }
    how_to_apply: { type: longvarchar, required: true }
    token:        { type: varchar(255), required: true, index: unique }
    is_public:    { type: boolean, required: true, default: 1 }
    is_activated: { type: boolean, required: true, default: 0 }
    email:        { type: varchar(255), required: true }
    expires_at:   { type: timestamp, required: true }
    created_at:   ~
    updated_at:   ~
  jobeet_affiliate:
    id:         ~
    url:        { type: varchar(255), required: true }
    email:      { type: varchar(255), required: true, index: unique }
    token:      { type: varchar(255), required: true }
    is_active:  { type: boolean, required: true, default: 0 }
    created_at: ~
  jobeet_category_affiliate:
    category_id:  { type: integer, foreignTable: jobeet_category, foreignReference: id, required: true, primaryKey: 
true, onDelete: cascade }
    affiliate_id: { type: integer, foreignTable: jobeet_affiliate, foreignReference: id, required: true, primaryKey: 
true, onDelete: cascade }
config/schema.yml


propel:
  jobeet_category:
    id:   ~
    name: { type: varchar(255),
            required: true,
            index: unique
          }
config/schema.yml
jobeet_job:
    id:           ~
    category_id:  { type: integer, foreignTable: jobeet_category, 
foreignReference: id, required: true }
    type:         { type: varchar(255) }
    company:      { type: varchar(255), required: true }
    logo:         { type: varchar(255) }
    url:          { type: varchar(255) }
    position:     { type: varchar(255), required: true }
    location:     { type: varchar(255), required: true }
    description:  { type: longvarchar, required: true }
    how_to_apply: { type: longvarchar, required: true }
    token:        { type: varchar(255), required: true, index: 
unique }
    is_public:    { type: boolean, required: true, default: 1 }
    is_activated: { type: boolean, required: true, default: 0 }
    email:        { type: varchar(255), required: true }
    expires_at:   { type: timestamp, required: true }
    created_at:   ~
    updated_at:   ~
config/schema.yml



jobeet_affiliate:
    id:         ~
    url:        { type: varchar(255), required: true }
    email:      { type: varchar(255), required: true, index: unique }
    token:      { type: varchar(255), required: true }
    is_active:  { type: boolean, required: true, default: 0 }
    created_at: ~
config/schema.yml
jobeet_category_affiliate:
    category_id:  {
      type: integer,
      foreignTable: jobeet_category,
      foreignReference: id,
      required: true,
      primaryKey: true,
      onDelete: cascade
    }
    affiliate_id: {
      type: integer,
      foreignTable: jobeet_affiliate,
      foreignReference: id,
      required: true,
      primaryKey: true,
      onDelete: cascade
    }
config/schema.yml


    type: boolean, tinyint, smallint, integer, bigint, double, float, 
•
    real, decimal, char, varchar(size), longvarchar, date, time, 
    timestamp, blob, clob

    required: true, false
•

    index: true, false
•

    primaryKey: true, false
•

    foreignKey, foreignReference
•
La base de datos
$ mysqladmin ‐uroot ‐p create jobeet


$ symfony configure:database
“mysql:host=localhost;dbname=jobeet”
root ConTraSenA

                config/databases.yml
El ORM
$ symfony propel:build‐sql
                     data/sql/

$ symfony propel:insert‐sql ‐‐no‐confirmation

$ symfony propel:build‐model
                      lib/model/
extends
    JobeetJob
•
    BaseJobeetJob
•
                          extends
    JobeetJobPeer
•
    BaseJobeetJobPeer
•
$job = new JobeetJob();
$job‐>setPosition('Web developer');
$job‐>save();

echo $job‐>getPosition();

$job‐>delete();
$category = new JobeetCategory(); 
$category‐>setName('Programming');

$job = new JobeetJob();
$job‐>setCategory($category);
$ symfony propel:build‐all ‐‐no‐confirmation
$ symfony propel:build‐sql
    $ symfony propel:insert‐sql
    $ symfony propel:build‐model
    $ symfony propel:build‐forms
+   $ symfony propel:build‐filters

$ symfony propel:build‐all
$ symfony cc
   Borra la caché de Symfony
•
• Ejecutar siempre que añades 
  clases (autoload)
• La solución de casi todos los 
  errores de los principiantes
$ symfony cache:clear
$ symfony cache:cl
$ symfony ca:c
$ symfony cc
Los datos iniciales
data/fixtures/

    Datos iniciales
•
    Datos de prueba
•
    Datos de usuarios
•
data/fixtures/010_categories.yml




JobeetCategory:
  design:        { name: Design }
  programming:   { name: Programming }
  manager:       { name: Manager }
  administrator: { name: Administrator }
data/fixtures/020_jobs.yml
JobeetJob:
  job_sensio_labs:
    category_id:  programming
    type:         full‐time
    company:      Sensio Labs
    logo:         sensio‐labs.gif
    url:          http://www.sensiolabs.com/
    position:     Web Developer
    location:     Paris, France
    description:  |
      You have already developed websites with symfony and you want
      to work with Open‐Source technologies. You have a minimum of 
      3 years experience in web development with PHP or Java and
      you wish to participate to development of Web 2.0 sites using
      the best frameworks available.
    how_to_apply: |
      Send your resume to fabien.potencier [at] sensio.com
    is_public:    true
    is_activated: true
    token:        job_sensio_labs
    email:        job@example.com
    expires_at:   2010‐10‐10
$ symfony propel:data‐load
$ symfony propel:build‐sql
    $ symfony propel:insert‐sql
    $ symfony propel:build‐model
    $ symfony propel:build‐forms
    $ symfony propel:build‐filters
+   $ symfony propel:data‐load

$ symfony propel:build‐all‐load
Probando la 
aplicación en el 
  navegador
proyecto                jobeet
aplicación




                                 backend
             frontend



               job
módulo
$ symfony propel:generate‐module
‐‐with‐show ‐‐non‐verbose‐templates
frontend job JobeetJob

      frontend/modules/job
          actions/
          templates/
frontend/modules/job/actions/actions.class.php



 index                   edit
 show                    update
                         delete
 new
 create
http://jobeet.localhost/frontend_dev.php/job



 frontend
 _dev
 job
Representación 
    Objeto       textual



             _ _toString()
Categoría
lib/model/JobeetCategory.php


class JobeetCategory extends BaseJobeetCategory
{
  public function __toString()
  {
    return $this‐>getName();
  }
}
lib/model/JobeetJob.php

class JobeetJob extends BaseJobeetJob
{
  public function __toString()
  {
    return sprintf(
       '%s at %s (%s)',
       $this‐>getPosition(),
       $this‐>getCompany(),
       $this‐>getLocation()
    );
  }
}
lib/model/JobeetAffiliate.php



class JobeetAffiliate extends BaseJobeetAffiliate
{
  public function __toString()
  {
    return $this‐>getUrl();
  }
}
http://jobeet.localhost/frontend_dev.php/job
Capítulo 4

El controlador y 
la vista
La arquitectura MVC
¿Cómo se programaba con PHP en 
           el siglo pasado?



1 página del        1 archivo PHP 
                =
  sitio web         diferente
¿Cómo se programaba con PHP en 
            el siglo pasado?
                                inicialización y 
                                configuración
    lógica de 
     negocio

                                acceso a BBDD

     generar 
código HTML


                   pagina.php
Modelo
Vista
Controlador
Modelo
 Directorio /lib/model
Vista
 Directorios templates/
Controlador
 Archivos index.php y frontend_dev.php
 Archivos actions.class.php
El layout
patrón de diseño decorator




apps/frontend/templates/layout.php
apps/frontend/templates/layout.php

<!DOCTYPE html PUBLIC quot;‐//W3C//DTD XHTML 1.0 Transitional//ENquot;
quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1‐transitional.dtdquot;>
<html xmlns=quot;http://www.w3.org/1999/xhtmlquot; xml:lang=quot;enquot; lang=quot;enquot;>
<head>
  <title>Jobeet ‐ Your best job board</title>
  <link rel=quot;shortcut iconquot; href=quot;/favicon.icoquot; />
  <?php include_javascripts() ?>
  <?php include_stylesheets() ?>
</head>
<body>
  ...
  <div class=quot;contentquot;>
   <?php echo $sf_content ?>
  </div>
</body>
</html>
Plantillas Symfony

• Archivos PHP 
normales
• Existe un plugin 
para Smarty
• Symfony 2.0 podría 
incluir plantillas
Las hojas de estilos, 
imágenes y archivos 
     JavaScript
helpers
<head>
  ...
  <?php include_stylesheets() ?>
</head>
apps/frontend/config/view.yml
default:
  http_metas:
    content‐type: text/html
  metas:
    #title: symfony project
    #description: symfony project
    #keywords: symfony, project
    #language: en
    #robots: index, follow

 stylesheets: [main.css]

 javascripts: []

 has_layout: on
 layout: layout
apps/frontend/config/view.yml
default:
  ...
  stylesheets:  [main.css, jobs.css, job.css]
 ...



<link rel=quot;stylesheetquot; type=quot;text/cssquot; 
media=quot;screenquot; href=quot;/css/main.cssquot; />
<link rel=quot;stylesheetquot; type=quot;text/cssquot; 
media=quot;screenquot; href=quot;/css/jobs.cssquot; />
<link rel=quot;stylesheetquot; type=quot;text/cssquot; 
media=quot;screenquot; href=quot;/css/job.cssquot; />
apps/frontend/config/view.yml
default:
  ...
  stylesheets:  [main.css, jobs.css, job]
 ...



<link rel=quot;stylesheetquot; type=quot;text/cssquot; 
media=quot;screenquot; href=quot;/css/main.cssquot; />
<link rel=quot;stylesheetquot; type=quot;text/cssquot; 
media=quot;screenquot; href=quot;/css/jobs.cssquot; />
<link rel=quot;stylesheetquot; type=quot;text/cssquot; 
media=quot;screenquot; href=quot;/css/job.cssquot; />
apps/frontend/config/view.yml
default:
  ...
  stylesheets:  [main.css, /css/v2/jobs.css]
 ...



<link rel=quot;stylesheetquot; type=quot;text/cssquot; 
media=quot;screenquot; href=quot;/css/main.cssquot; />
<link rel=quot;stylesheetquot; type=quot;text/cssquot; 
media=quot;screenquot; href=quot;/css/v2/jobs.cssquot; />
apps/frontend/config/view.yml
default:
 ...
stylesheets: [main.css, jobs: { media: print } ]
...



<link rel=quot;stylesheetquot; type=quot;text/cssquot; 
media=quot;screenquot; href=quot;/css/main.cssquot; />
<link rel=quot;stylesheetquot; type=quot;text/cssquot; 
media=quot;printquot; href=quot;/css/jobs.cssquot; />
metas:
                                       Symfony
 title: El título 1
  metas:
                                       Proyecto
   title: El título 2
    metas:
                                       Aplicación
     title: El título 3
      metas:
                                       Módulo
       title: El título 4




                            view.yml
Symfony
 lib/vendor/symfony/lib/config/config/view.yml
Proyecto
 config/view.yml
Aplicación
 apps/frontend/config/view.yml
Módulo
 apps/frontend/modules/job/config/view.yml
metas:
                               stylesheets: [job]

<?php
use_stylesheet(‘job.css’)                           view.yml
?>




                  plantilla
                                            plantilla
La portada del módulo 
   de las ofertas de 
        trabajo
apps/
 frontend/
  modules/
   job/
    actions/
     actions.class.php
    templates/
     indexSuccess.php
acción

    +
=
    plantilla
http://jobeet.localhost/frontend_dev.php/job/index

  frontend (aplicación)
  _dev (entorno)
  job (módulo)
  index (acción executeIndex y 
  plantilla indexSuccess)
apps/frontend/modules/job/actions/actions.class.php



class jobActions extends sfActions
{
  public function executeIndex(sfWebRequest $request)
  {
    $this‐>jobeet_job_list =
      JobeetJobPeer::doSelect(new Criteria());
  }

    // ...
}
SELECT
    [ALL | DISTINCT | DISTINCTROW ]
      [HIGH_PRIORITY]
      [STRAIGHT_JOIN]
      [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
      [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
    select_expr [, select_expr ...]
    [FROM table_references
    [WHERE where_condition]
    [GROUP BY {col_name | expr | position}
      [ASC | DESC], ... [WITH ROLLUP]]
    [HAVING where_condition]
    [ORDER BY {col_name | expr | position}
      [ASC | DESC], ...]
    [LIMIT {[offset,] row_count | row_count OFFSET offset}]
    [PROCEDURE procedure_name(argument_list)]
    [INTO OUTFILE 'file_name' export_options
      | INTO DUMPFILE 'file_name'
      | INTO var_name [, var_name]]
    [FOR UPDATE | LOCK IN SHARE MODE]]
apps/frontend/modules/job/templates/indexSuccess.php



<?php foreach ($jobeet_job_list as $jobeet_job): ?>
  ...
  <td>
    <a href=quot;...quot;>
       <?php echo $jobeet_job‐>getId() ?>
    </a>
  </td>
  ...
<?php endforeach; ?> 
La plantilla de la página 
   de una oferta de 
        trabajo
Slots
<title>Jobeet</title>   <title>




      layout                 plantilla
<title>             </title>   Título de la página




        layout                      plantilla
apps/frontend/templates/layout.php
<title>
  <?php include_slot('title') ?>
</title>

         apps/frontend/modules/job/templates/indexSuccess.php

<?php slot('title', 'Título de la página') ?> 

<?php slot(
  'title',
  sprintf('%s is looking for a %s',
    $job‐>getCompany(),
    $job‐>getPosition()
  )
) ?> 
La acción de la página 
   de una oferta de 
        trabajo
apps/frontend/modules/job/actions/actions.class.php



public function executeShow(sfWebRequest $request)
{
  $this‐>job = JobeetJobPeer::retrieveByPk(
     $request‐>getParameter('id')
  );

    $this‐>forward404Unless($this‐>job);
}
La petición y la 
   respuesta
objeto sfWebRequest

class jobActions extends sfActions
{
  public function executeShow(sfWebRequest   $request)
  {
    $peticion = $request;
    $origen   = $peticion‐>getReferer();
    $metodo   = $peticion‐>getMethod();
  }

    // ...
}
Nombre del método                  Equivalente de PHP
getMethod()           $_SERVER['REQUEST_METHOD']

getUri()              $_SERVER['REQUEST_URI']

getReferer()          $_SERVER['HTTP_REFERER']

getHost()             $_SERVER['HTTP_HOST']

getLanguages()        $_SERVER['HTTP_ACCEPT_LANGUAGE']

getCharsets()         $_SERVER['HTTP_ACCEPT_CHARSET']

isXmlHttpRequest()    $_SERVER['X_REQUESTD_WITH'] == 'XMLHttpRequest'

getHttpHeader()       $_SERVER

getCookie()           $_COOKIE

isSecure()            $_SERVER['HTTPS']

getFiles()            $_FILES

getGetParameter()     $_GET

getPostParameter()    $_POST

getUrlParameter()     $_SERVER['PATH_INFO']

getRemoteAddress()    $_SERVER['REMOTE_ADDR']
public function executeShow(sfWebRequest $request)
{
  ...
  $request‐>getParameter('id');

    ...

}


/ruta1/ruta2/ruta3?id=3&clave1=
valor1&clave2=valor2
objeto sfWebResponse

class jobActions extends sfActions
{
  public function executeShow(sfWebRequest $request)
  {
    $respuesta = $this‐>getResponse();
    $respuesta‐>setStatusCode(404);
    $respuesta‐>addStyleSheet('/css/job.css');
    $respuesta‐>setTitle('Título de la página');
  }

    // ...
}
archivo de configuración
 metas:
   stylesheets: [job]

plantilla
         use_stylesheet('job.css')
 <?php                               ?>


acción
 $this‐>getResponse()‐>
   addStyleSheet('/css/job.css');
Capítulo 5

El sistema de 
enrutamiento
URL
internet     symfony




URL           URI
     sistema de 
    enrutamiento
URI 'job/show?id='.$job‐>getId()

           url_for()

      job/show/id/1
URL
URI

modulo/accion?clave1=
valor1&clave2=valor2&
...
Configurando el 
 enrutamiento
apps/frontend/config/routing.yml


homepage:
  url: /
  param: { module: default, action: index }

default_index:
  url: /:module
  param: { action: index }

default:
  url: /:module/:action/*
nombre
                   patrón
default_index:
  url: /:module
  param: { action: index }

        parámetros
homepage:
  url: /
  param: { module: default, action: index }

default_index:
  url: /:module
  param: { action: index }

default:
  url: /:module/:action/* 




                      /job
/frontend_dev.php/job
1
                          entorno
        aplicación                     ???

                          ¿acción?
       ¿módulo?
    apps/frontend/config/routing.yml
2
                     default_index:
/job                   url: /:module
                       param: { action: index }


:module = job = módulo
3    apps/frontend/config/routing.yml
default_index:
                             acción = index
  url: /:module
  param: { action: index }



    /frontend_dev.php/job
4
aplicación = frontend        módulo = job
entorno = dev                acción = index
url_for()
URI                           URL

url_for('job/show?id='.$job‐>getId())


          /job/show/id/1
url_for()
URI                           URL


url_for('@default?id='.$job‐>getId())
Personalizando el 
 enrutamiento
apps/frontend/config/routing.yml

homepage:
  url: /
  param: { module: job, action: index }

default_index:
  url: /:module
  param: { action: index }

default:
  url: /:module/:action/* 
<h1>
 <a href=quot;<?php echo url_for('@homepage') ?>quot;>
  <img src=quot;/images/jobeet.gifquot; alt=quot;Jobeetquot; />
 </a>
</h1>
/job/sensio‐labs/paris‐france/1/web‐developer


1. Identificar el patrón de la URL

2. Incluir la ruta a routing.yml

3. Añadir las restricciones adecuadas
/job/sensio‐labs/paris‐france/1/web‐developer


1. Identificar el patrón de la URL


    /job/:company/:location/:id/:position
/job/sensio‐labs/paris‐france/1/web‐developer


 2. Incluir la ruta en routing.yml

job_show_user:
 url:   /job/:company/:location/:id/:position
 param: { module: job, action: show }
url_for('job/show?'.
  'id='.$job‐>getId().
  '&company='.$job‐>getCompany().
  '&location='.$job‐>getLocation().
  '&position='.$job‐>getPosition()
)
url_for(array(
  'module'   => 'job',
  'action'   => 'show',
  'id'       => $job‐>getId(),
  'company' => $job‐>getCompany(),
  'location' => $job‐>getLocation(),
  'position' => $job‐>getPosition(), 
))
Requisitos
/job/sensio‐labs/paris‐france/1/web‐developer


 3. Añadir las restricciones adecuadas

job_show_user:
 url:   /job/:company/:location/:id/:position
 param: { module: job, action: show }
 requirements:
    id: d+
La clase sfRoute
HTTP     Navegadores      Symfony
GET
POST
HEAD
PUT
DELETE
job_show_user:
  url:     /job/:company/:location/:id/:position
  class: sfRequestRoute
  param:   { module: job, action: show }
  requirements:
    id: d+
    sf_method: [get]
La clase para las 
rutas basadas en 
     objetos
url_for('job/show?'.
  'id='.$job‐>getId().
  '&company='.$job‐>getCompany().
  '&location='.$job‐>getLocation().
  '&position='.$job‐>getPosition()
)
job_show_user:
  url:      /job/:company/:location/:id/:position
  class:  sfPropelRoute
  options:
   model: JobeetJob
   type:  object
  param:     { module: job, action: show }
  requirements:
    id: d+
    sf_method: [get]
url_for('job/show?'.
  'id='.$job‐>getId().
  '&company='.$job‐>getCompany().
  '&location='.$job‐>getLocation().
  '&position='.$job‐>getPosition()
)



url_for('job_show_user', $job)

url_for(array(
  'sf_route'   => 'job_show_user',
  'sf_subject' => $job
))
Lo que queremos…
/job/sensio‐labs/paris‐france/1/web‐developer


Lo que tenemos…
/job/Sensio+Labs/Paris%2C+France/1/Web+Developer
getId()
id
name                         getName()
description
                Job          getDescription()
...

                            getSlug()
schema.yml                getShortDescription()
               getters
              virtuales
slug

Comienza el curso de Symfony en Vitoria‐Gasteiz

www.symfony.es/2009/01/29/comienza‐el‐curso‐de‐symfony‐en‐vitoria‐gasteiz




Twitto, el framework PHP más pequeño

www.symfony.es/2009/01/11/twitto‐el‐framework‐php‐mas‐pequeno/
getId()
id
name                       getName()
description
                Job        getDescription()
...

                           getCompanySlug()
                          getPositionSlug()
schema.yml
                          getLocationSlug()
               getters
              virtuales
lib/model/JobeetJob.php

public function getCompanySlug() {
  return Jobeet::slugify($this‐>getCompany());
}

public function getPositionSlug() {
  return Jobeet::slugify($this‐>getPosition());
}

public function getLocationSlug() {
  return Jobeet::slugify($this‐>getLocation());
}
lib/Jobeet.class.php

class Jobeet
{
  static public function slugify($text)
  {
    // replace all non letters or digits by ‐
    $text = preg_replace('/W+/', '‐', $text);

        // trim and lowercase
        $text = strtolower(trim($text, '‐'));

        return $text;
    }
}
job_show_user:
 url: /job/:company_slug/:location_slug/:id/:position_slug
 class:   sfPropelRoute
 options: { model: JobeetJob, type:  object }
 param:   { module: job, action: show }
 requirements:
  id: d+
  sf_method: [get]
class jobActions extends sfActions
{
  public function executeShow(sfWebRequest $request)
  {
    $this‐>job = JobeetJobPeer::retrieveByPk($request‐>getParameter('id'));
    $this‐>forward404Unless($this‐>job);
  }

    // ...
}

class jobActions extends sfActions
{
  public function executeShow(sfWebRequest $request)
  {
    $this‐>job = $this‐>getRoute()‐>getObject(); 
  }

     // ...
}
Enrutamiento en 
   acciones y 
    plantillas
<?php echo link_to(
  quot;Texto del enlacequot;,
  'job_show_user',
  $job
) ?>

<a href=quot;
  <?php echo url_for(
     'job_show_user',
     $job,
     true
  ); ?>quot;>
Texto del enlace
</a>
class jobActions extends sfActions
{
    public function executeIndex(sfWebRequest   $request)
    {
        // ...

        $this‐>redirect(
           $this‐>generateUrl('job_show_user', $job)
        );
    }

    // ...
}
La clase de las 
colecciones de 
     rutas
job:
  class:   sfPropelRouteCollection
  options: { model: JobeetJob }

job_show_user:
 url: /job/:company_slug/:location_slug/:id/:position_slug
 class: sfPropelRoute
 options: { model: JobeetJob, type:  object }
 param: { module: job, action: show }
 requirements:
  id: d+
  sf_method: [get]
$ php symfony app:routes frontend

More Related Content

What's hot

Drupal Cms Prezentace
Drupal Cms PrezentaceDrupal Cms Prezentace
Drupal Cms PrezentaceTomáš Kafka
 
Acções acreditadas fevereiro 2012
Acções acreditadas fevereiro 2012Acções acreditadas fevereiro 2012
Acções acreditadas fevereiro 2012João Lima
 
การตกแต่งพื้นหลังให้กับสไลด์
การตกแต่งพื้นหลังให้กับสไลด์การตกแต่งพื้นหลังให้กับสไลด์
การตกแต่งพื้นหลังให้กับสไลด์เทวัญ ภูพานทอง
 
Presentation Ubifrance NTIC Corée Sud 2010 07 06
Presentation Ubifrance NTIC Corée Sud 2010 07 06Presentation Ubifrance NTIC Corée Sud 2010 07 06
Presentation Ubifrance NTIC Corée Sud 2010 07 06Olivier Epinette
 
Fundamentos del ajedrez jose raul capablanca - es
Fundamentos del ajedrez   jose raul capablanca - esFundamentos del ajedrez   jose raul capablanca - es
Fundamentos del ajedrez jose raul capablanca - esdocente20081
 
PDF 14.5 Conflictivitat social i política. I.Aguilera, A.BarrabiñO I G.Donaire
PDF 14.5 Conflictivitat social i política. I.Aguilera, A.BarrabiñO I G.DonairePDF 14.5 Conflictivitat social i política. I.Aguilera, A.BarrabiñO I G.Donaire
PDF 14.5 Conflictivitat social i política. I.Aguilera, A.BarrabiñO I G.Donaireriberamontserrat
 
Aeman dee ekkadunnaaru
Aeman dee ekkadunnaaruAeman dee ekkadunnaaru
Aeman dee ekkadunnaaruvenkatesha9
 
Silex. Микрофреймворк для микроприложений
Silex. Микрофреймворк для микроприложенийSilex. Микрофреймворк для микроприложений
Silex. Микрофреймворк для микроприложенийSoftline
 
Food Gh Fee Structures
Food Gh Fee StructuresFood Gh Fee Structures
Food Gh Fee Structuresmsdhillon72
 
Romo morin ana paola la educacion democratica en john dewey
Romo morin ana paola   la educacion democratica en john deweyRomo morin ana paola   la educacion democratica en john dewey
Romo morin ana paola la educacion democratica en john deweyAdalberto
 
Mantovani Gruppo 2003 Insieme Per La Ricerca Milano 21 Settembre
Mantovani Gruppo 2003 Insieme Per La Ricerca  Milano 21 SettembreMantovani Gruppo 2003 Insieme Per La Ricerca  Milano 21 Settembre
Mantovani Gruppo 2003 Insieme Per La Ricerca Milano 21 SettembreScienzainrete
 

What's hot (18)

Banner kiri kanan1
Banner kiri kanan1Banner kiri kanan1
Banner kiri kanan1
 
Index
IndexIndex
Index
 
Form refactoring
Form refactoringForm refactoring
Form refactoring
 
Session4
Session4Session4
Session4
 
Drupal Cms Prezentace
Drupal Cms PrezentaceDrupal Cms Prezentace
Drupal Cms Prezentace
 
Acções acreditadas fevereiro 2012
Acções acreditadas fevereiro 2012Acções acreditadas fevereiro 2012
Acções acreditadas fevereiro 2012
 
การตกแต่งพื้นหลังให้กับสไลด์
การตกแต่งพื้นหลังให้กับสไลด์การตกแต่งพื้นหลังให้กับสไลด์
การตกแต่งพื้นหลังให้กับสไลด์
 
CRC - Vietnamese version
CRC - Vietnamese versionCRC - Vietnamese version
CRC - Vietnamese version
 
Templating WordPress
Templating WordPressTemplating WordPress
Templating WordPress
 
Presentation Ubifrance NTIC Corée Sud 2010 07 06
Presentation Ubifrance NTIC Corée Sud 2010 07 06Presentation Ubifrance NTIC Corée Sud 2010 07 06
Presentation Ubifrance NTIC Corée Sud 2010 07 06
 
Fundamentos del ajedrez jose raul capablanca - es
Fundamentos del ajedrez   jose raul capablanca - esFundamentos del ajedrez   jose raul capablanca - es
Fundamentos del ajedrez jose raul capablanca - es
 
PDF 14.5 Conflictivitat social i política. I.Aguilera, A.BarrabiñO I G.Donaire
PDF 14.5 Conflictivitat social i política. I.Aguilera, A.BarrabiñO I G.DonairePDF 14.5 Conflictivitat social i política. I.Aguilera, A.BarrabiñO I G.Donaire
PDF 14.5 Conflictivitat social i política. I.Aguilera, A.BarrabiñO I G.Donaire
 
Aeman dee ekkadunnaaru
Aeman dee ekkadunnaaruAeman dee ekkadunnaaru
Aeman dee ekkadunnaaru
 
Silex. Микрофреймворк для микроприложений
Silex. Микрофреймворк для микроприложенийSilex. Микрофреймворк для микроприложений
Silex. Микрофреймворк для микроприложений
 
La pídora del día después.
La pídora del día después.La pídora del día después.
La pídora del día después.
 
Food Gh Fee Structures
Food Gh Fee StructuresFood Gh Fee Structures
Food Gh Fee Structures
 
Romo morin ana paola la educacion democratica en john dewey
Romo morin ana paola   la educacion democratica en john deweyRomo morin ana paola   la educacion democratica en john dewey
Romo morin ana paola la educacion democratica en john dewey
 
Mantovani Gruppo 2003 Insieme Per La Ricerca Milano 21 Settembre
Mantovani Gruppo 2003 Insieme Per La Ricerca  Milano 21 SettembreMantovani Gruppo 2003 Insieme Per La Ricerca  Milano 21 Settembre
Mantovani Gruppo 2003 Insieme Per La Ricerca Milano 21 Settembre
 

Viewers also liked

Freebase - Semantic Technologies 2010 Code Camp
Freebase - Semantic Technologies 2010 Code CampFreebase - Semantic Technologies 2010 Code Camp
Freebase - Semantic Technologies 2010 Code CampJamie Taylor
 
A PHP Christmas Miracle - 3 Frameworks, 1 app
A PHP Christmas Miracle - 3 Frameworks, 1 appA PHP Christmas Miracle - 3 Frameworks, 1 app
A PHP Christmas Miracle - 3 Frameworks, 1 appRyan Weaver
 
$kernel->infect(): Creating a cryptovirus for Symfony2 apps
$kernel->infect(): Creating a cryptovirus for Symfony2 apps$kernel->infect(): Creating a cryptovirus for Symfony2 apps
$kernel->infect(): Creating a cryptovirus for Symfony2 appsRaul Fraile
 
Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Fabien Potencier
 
Learning To Love Forms (Web Directions South '07)
Learning To Love Forms (Web Directions South '07)Learning To Love Forms (Web Directions South '07)
Learning To Love Forms (Web Directions South '07)Aaron Gustafson
 

Viewers also liked (6)

Freebase Schema
Freebase SchemaFreebase Schema
Freebase Schema
 
Freebase - Semantic Technologies 2010 Code Camp
Freebase - Semantic Technologies 2010 Code CampFreebase - Semantic Technologies 2010 Code Camp
Freebase - Semantic Technologies 2010 Code Camp
 
A PHP Christmas Miracle - 3 Frameworks, 1 app
A PHP Christmas Miracle - 3 Frameworks, 1 appA PHP Christmas Miracle - 3 Frameworks, 1 app
A PHP Christmas Miracle - 3 Frameworks, 1 app
 
$kernel->infect(): Creating a cryptovirus for Symfony2 apps
$kernel->infect(): Creating a cryptovirus for Symfony2 apps$kernel->infect(): Creating a cryptovirus for Symfony2 apps
$kernel->infect(): Creating a cryptovirus for Symfony2 apps
 
Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2
 
Learning To Love Forms (Web Directions South '07)
Learning To Love Forms (Web Directions South '07)Learning To Love Forms (Web Directions South '07)
Learning To Love Forms (Web Directions South '07)
 

More from Javier Eguiluz

deSymfony 2017: Symfony 4, Symfony Flex y el futuro de Symfony
deSymfony 2017: Symfony 4, Symfony Flex y el futuro de SymfonydeSymfony 2017: Symfony 4, Symfony Flex y el futuro de Symfony
deSymfony 2017: Symfony 4, Symfony Flex y el futuro de SymfonyJavier Eguiluz
 
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)Javier Eguiluz
 
Mastering Twig (DrupalCon Barcelona 2015)
Mastering Twig (DrupalCon Barcelona 2015)Mastering Twig (DrupalCon Barcelona 2015)
Mastering Twig (DrupalCon Barcelona 2015)Javier Eguiluz
 
Symfony tips and tricks
Symfony tips and tricksSymfony tips and tricks
Symfony tips and tricksJavier Eguiluz
 
Twig, el nuevo motor de plantillas de Drupal 8
Twig, el nuevo motor de plantillas de Drupal 8Twig, el nuevo motor de plantillas de Drupal 8
Twig, el nuevo motor de plantillas de Drupal 8Javier Eguiluz
 
Silex, desarrollo web ágil y profesional con PHP
Silex, desarrollo web ágil y profesional con PHPSilex, desarrollo web ágil y profesional con PHP
Silex, desarrollo web ágil y profesional con PHPJavier Eguiluz
 
Twig avanzado (sf2Vigo)
Twig avanzado (sf2Vigo)Twig avanzado (sf2Vigo)
Twig avanzado (sf2Vigo)Javier Eguiluz
 
Desymfony 2012 - Concurso de diseño
Desymfony 2012 - Concurso de diseñoDesymfony 2012 - Concurso de diseño
Desymfony 2012 - Concurso de diseñoJavier Eguiluz
 
Desymfony 2011 - Tutorial #5: Backend
Desymfony 2011 - Tutorial #5: BackendDesymfony 2011 - Tutorial #5: Backend
Desymfony 2011 - Tutorial #5: BackendJavier Eguiluz
 
Desymfony 2011 - Tutorial #1: Instalacion y primeros pasos
Desymfony 2011 - Tutorial #1: Instalacion y primeros pasosDesymfony 2011 - Tutorial #1: Instalacion y primeros pasos
Desymfony 2011 - Tutorial #1: Instalacion y primeros pasosJavier Eguiluz
 
Desymfony 2011 - Introducción a Symfony2
Desymfony 2011 - Introducción a Symfony2Desymfony 2011 - Introducción a Symfony2
Desymfony 2011 - Introducción a Symfony2Javier Eguiluz
 
Symfony2, Jornadas Symfony
Symfony2, Jornadas SymfonySymfony2, Jornadas Symfony
Symfony2, Jornadas SymfonyJavier Eguiluz
 
Curso Symfony - Anexos
Curso Symfony - AnexosCurso Symfony - Anexos
Curso Symfony - AnexosJavier Eguiluz
 
Curso Symfony - Clase 4
Curso Symfony - Clase 4Curso Symfony - Clase 4
Curso Symfony - Clase 4Javier Eguiluz
 
Curso Symfony - Clase 3
Curso Symfony - Clase 3Curso Symfony - Clase 3
Curso Symfony - Clase 3Javier Eguiluz
 
Curso Symfony - Clase 2
Curso Symfony - Clase 2Curso Symfony - Clase 2
Curso Symfony - Clase 2Javier Eguiluz
 

More from Javier Eguiluz (20)

deSymfony 2017: Symfony 4, Symfony Flex y el futuro de Symfony
deSymfony 2017: Symfony 4, Symfony Flex y el futuro de SymfonydeSymfony 2017: Symfony 4, Symfony Flex y el futuro de Symfony
deSymfony 2017: Symfony 4, Symfony Flex y el futuro de Symfony
 
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
 
Mastering Twig (DrupalCon Barcelona 2015)
Mastering Twig (DrupalCon Barcelona 2015)Mastering Twig (DrupalCon Barcelona 2015)
Mastering Twig (DrupalCon Barcelona 2015)
 
Symfony tips and tricks
Symfony tips and tricksSymfony tips and tricks
Symfony tips and tricks
 
Twig, el nuevo motor de plantillas de Drupal 8
Twig, el nuevo motor de plantillas de Drupal 8Twig, el nuevo motor de plantillas de Drupal 8
Twig, el nuevo motor de plantillas de Drupal 8
 
Twig tips and tricks
Twig tips and tricksTwig tips and tricks
Twig tips and tricks
 
Silex, desarrollo web ágil y profesional con PHP
Silex, desarrollo web ágil y profesional con PHPSilex, desarrollo web ágil y profesional con PHP
Silex, desarrollo web ágil y profesional con PHP
 
Wallpaper Notifier
Wallpaper NotifierWallpaper Notifier
Wallpaper Notifier
 
Backend (sf2Vigo)
Backend (sf2Vigo)Backend (sf2Vigo)
Backend (sf2Vigo)
 
Twig avanzado (sf2Vigo)
Twig avanzado (sf2Vigo)Twig avanzado (sf2Vigo)
Twig avanzado (sf2Vigo)
 
Desymfony 2012 - Concurso de diseño
Desymfony 2012 - Concurso de diseñoDesymfony 2012 - Concurso de diseño
Desymfony 2012 - Concurso de diseño
 
Desymfony 2011 - Twig
Desymfony 2011 - TwigDesymfony 2011 - Twig
Desymfony 2011 - Twig
 
Desymfony 2011 - Tutorial #5: Backend
Desymfony 2011 - Tutorial #5: BackendDesymfony 2011 - Tutorial #5: Backend
Desymfony 2011 - Tutorial #5: Backend
 
Desymfony 2011 - Tutorial #1: Instalacion y primeros pasos
Desymfony 2011 - Tutorial #1: Instalacion y primeros pasosDesymfony 2011 - Tutorial #1: Instalacion y primeros pasos
Desymfony 2011 - Tutorial #1: Instalacion y primeros pasos
 
Desymfony 2011 - Introducción a Symfony2
Desymfony 2011 - Introducción a Symfony2Desymfony 2011 - Introducción a Symfony2
Desymfony 2011 - Introducción a Symfony2
 
Symfony2, Jornadas Symfony
Symfony2, Jornadas SymfonySymfony2, Jornadas Symfony
Symfony2, Jornadas Symfony
 
Curso Symfony - Anexos
Curso Symfony - AnexosCurso Symfony - Anexos
Curso Symfony - Anexos
 
Curso Symfony - Clase 4
Curso Symfony - Clase 4Curso Symfony - Clase 4
Curso Symfony - Clase 4
 
Curso Symfony - Clase 3
Curso Symfony - Clase 3Curso Symfony - Clase 3
Curso Symfony - Clase 3
 
Curso Symfony - Clase 2
Curso Symfony - Clase 2Curso Symfony - Clase 2
Curso Symfony - Clase 2
 

Curso Symfony - Clase 1

Editor's Notes

  1. http://xkcd.com/285/
  2. http://www.ibm.com/developerworks/xml/library/x-matters23.html