Frameworks de desarrollo Symfony Clase 1 Javier Eguíluz [email protected] Esta obra dispone de una licencia d
Views 92 Downloads 2 File size 2MB
Frameworks de desarrollo
Symfony Clase 1
Javier Eguíluz [email protected]
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
aprendizaje
Curva de aprendizaje de Symfony
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 aplicación
jobeet
frontend
backend
$ symfony generate:project jobeet
apps/
log/
cache/
plugins/
config/
test/
lib/
web/
$ symfony generate:app jobeet ‐‐escaping‐strategy=on ‐‐csrf‐secret=UniqueSecret
frontend
frontend/ config/ lib/ modules/ templates/
‐‐escaping‐strategy
‐‐csrf‐secret
XSS 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
XML
2002‐10‐04 Draw
2002‐10‐06
White
YAML players: Vladimir Kramnik: &kramnik rating: 2700 status: GM Deep Fritz: &fritz rating: 2700 status: Computer David Mertz: &mertz rating: 1400 status: Amateur matches: ‐ Date: 2002‐10‐04 White: *fritz Black: *kramnik Result: Draw ‐ Date: 2002‐10‐06 White: *kramnik Black: *fritz Result: White
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/ 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 }
schema.yml
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 JobeetJobPeer BaseJobeetJobPeer
extends
$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: [email protected] 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 aplicación módulo
jobeet
frontend
job
backend
$ 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
new
delete
create
http://jobeet.localhost/frontend_dev.php/job
frontend _dev job
Objeto
Categoría
Representación textual
_ _toString()
lib/model/
JobeetCategory.php
class JobeetCategory extends BaseJobeetCategory { public function __toString() { return $this‐>getName(); } }
lib/model/
class JobeetJob extends BaseJobeetJob { public function __toString() { return sprintf( '%s at %s (%s)', $this‐>getPosition(), $this‐>getCompany(), $this‐>getLocation() ); } }
JobeetJob.php
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 sitio web
=
1 archivo PHP 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
Jobeet ‐ Your best job board
...
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
...
apps/frontend/config/ 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
view.yml
apps/frontend/config/
view.yml
default: ...
stylesheets: [main.css, jobs.css, job.css] ...
apps/frontend/config/
view.yml
default: ...
stylesheets: [main.css, jobs.css, job] ...
apps/frontend/config/
view.yml
default: ...
stylesheets: [main.css, /css/v2/jobs.css] ...
apps/frontend/config/
view.yml
default: ...
stylesheets: [main.css, jobs: { media: print } ] ...
metas: title: El título 1
Symfony
metas: title: El título 2
Proyecto
metas: title: El título 3
Aplicación
metas: title: El título 4
Módulo
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]
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
...