Ieri abbiamo analizzato come symfony possa semplificare la gestione del database astraendo le differenze tra i vari motori di database e convertendo gli elementi dello schema relazionale in classi orientate agli oggetti. Abbiamo inoltre giocato con Propel per descrivere lo schema del database, creare le tabelle e popolare il database con alcuni dati iniziali.
Oggi andremo a personalizzare il modulo job
creato ieri. Il modulo job
contiene già tutto il codice di cui abbiamo bisogno per Jobeet:
- Una pagina per elencare tutte le offerte di lavoro
- Una pagina per creare una nuova offerta
- Una pagina per aggiornare un'offerta esistente
- Una pagina per cancellare un'offerta
Nonostante il codice sia pronto per essere usato com'è, rifattorizzeremo i template per attenerci il più possibile ai mockup di Jobeet.
L'architettura MVC
Se siete abituati a sviluppare siti web con PHP senza utilizzare un framework, probabilmente utilizzate il paradigma del singolo file PHP per singola pagina HTML. Questi file PHP probabilmente contengono lo stesso tipo di struttura: inizializzazione e configurazioni globali, business logic relativa alla pagina richiesta, recupero dei record dal database e infine il codice HTML che costruisce la pagina.
Potreste usare un motore per i template per separare la logica dall'HTML. Forse usate un layer per l'astrazione del database per separare l'interazione tra il modello e la business logic. Purtroppo il più delle volte finite per avere una grande quantità di codice che è un vero e proprio incubo da mantenere. È stato veloce da realizzare, ma con il passare del tempo è sempre più difficile apportare cambiamenti, specialmente perché nessuno eccetto voi capisce come è fatto e come funziona.
Come per tutti i problemi esistono piacevoli soluzioni. Per lo sviluppo web la soluzione più diffusa di questi tempi per organizzare il codice è rappresentata dal pattern architetturale MVC. Brevemente il pattern MVC definisce un modo per organizzare il proprio codice secondo la sua natura. Questo pattern separa il codice in tre strati:
Il Modello è lo strato che definisce la business logic (il database appartiene a questo strato). Probabilmente siete al corrente del fatto che symfony memorizza tutte le classi e i file relativi al Modello nella cartella
lib/model/
.La Vista rappresenta ciò con cui l'utente interagisce (un motore di template è parte di questo strato). In symfony lo strato della Vista è principalmente costituito da template PHP. Queste sono memorizzate in varie cartelle
templates
come vedremo in seguito.Il Controllore è la parte di codice che chiama il Modello per ottenere alcuni dati da passare alla Vista per visualizzarli attraverso il client. Quando abbiamo installato symfony il primo giorno abbiamo visto che tutte le richieste sono gestite dai front controller (
index.php
efrontend_dev.php
). Questi front controller delegano il vero lavoro alle azioni. Come abbiamo visto ieri queste azioni sono raggruppate in moduli.
Oggi utilizzeremo il mockup definito il giorno 2 per personalizzare l'homepage e la pagina delle offerte di lavoro. Inoltre le renderemo dinamiche. Lungo la strada perfezioneremo molte cose in molti file differenti per mostrare la struttura delle cartelle di symfony e come separare il codice tra i vari strati.
Il Layout
Per prima cosa se avete guardato con attenzione i mockup avrete notato che gran parte di ogni pagina sembra sempre la stessa. Sapere già che la duplicazione del codice è una cattiva pratica se stiamo parlando di codice HTML o PHP, perciò abbiamo bisogno di trovare un modo per prevenire il fatto che elementi comuni implichino duplicazione del codice.
Un modo per risolvere questo problema è quello di definire un header e un footer includendoli in ogni template:
Ma qui i file di header e footer non contengono HTML valido. Deve esserci una strada migliore. Invece di reinventate la ruota, utilizzeremo un altro design pattern per risolvere questo problema: il design pattern decorator. Il design pattern decorator risolve il problema agendo al contrario: il template viene decorato dopo che il contenuto è stato reso da un template globale, in symfony questo è definito come un layout:
Il layout di default di un'applicazione è chiamato layout.php
e può
essere trovato nella cartella apps/frontend/templates/
. Questa cartella
contiene tutti i template globali di un'applicazione.
Rimpiazzate il layout di default di symfony con il seguente codice:
<!-- apps/frontend/templates/layout.php --> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title>Jobeet - Your best job board</title> <link rel="shortcut icon" href="/favicon.ico" /> <?php include_javascripts() ?> <?php include_stylesheets() ?> </head> <body> <div id="container"> <div id="header"> <div class="content"> <h1><a href="<?php echo url_for('job/index') ?>"> <img src="/legacy/images/logo.jpg" alt="Jobeet Job Board" /> </a></h1> <div id="sub_header"> <div class="post"> <h2>Ask for people</h2> <div> <a href="<?php echo url_for('job/index') ?>">Post a Job</a> </div> </div> <div class="search"> <h2>Ask for a job</h2> <form action="" method="get"> <input type="text" name="keywords" id="search_keywords" /> <input type="submit" value="search" /> <div class="help"> Enter some keywords (city, country, position, ...) </div> </form> </div> </div> </div> </div> <div id="content"> <?php if ($sf_user->hasFlash('notice')): ?> <div class="flash_notice"> <?php echo $sf_user->getFlash('notice') ?> </div> <?php endif; ?> <?php if ($sf_user->hasFlash('error')): ?> <div class="flash_notice"> <?php echo $sf_user->getFlash('error') ?> </div> <?php endif; ?> <div class="content"> <?php echo $sf_content ?> </div> </div> <div id="footer"> <div class="content"> <span class="symfony"> <img src="/legacy/images/jobeet-mini.png" /> powered by <a href="/"> <img src="/legacy/images/symfony.gif" alt="symfony framework" /> </a> </span> <ul> <li><a href="">About Jobeet</a></li> <li class="feed"><a href="">Full feed</a></li> <li><a href="">Jobeet API</a></li> <li class="last"><a href="">Affiliates</a></li> </ul> </div> </div> </div> </body> </html>
Un template di symfony è solamente un semplice file PHP. Nel template del
layout ci sono chiamate a funzioni PHP e riferimenti a variabili PHP.
$sf_content
è la variabile più interessante: è definita dal framework stesso
e contiene l'HTML generato dall'azione.
Se navigate il modulo job
(http://www.jobeet.com.localhost/frontend_dev.php/job
)
potete vedere che tutte le azioni sono decorate dal layout.
I Fogli di stile, le Immagini e i Javascript
Dato che questo tutorial non riguarda il web design, abbiamo già preparato
tutte le risorse necessarie per Jobbet:
organizzeremo un concorso per il miglior design il giorno 21, abbiamo
scaricate l'archivio delle immagini
e mettetele nella cartella web/images
;
scarica tel'archivio dei fogli di stile
e metteteli nella cartella web/css/
.
note
Nel layout abbiamo incluso una favicon. Potete
scaricare quella di Jobeet
e metterla nella cartella web/
.
tip
Di default, il task generate:project
ha creato tre cartelle per i file degli
elementi grafici: web/legacy/images/
per le immagini, web/~css~/
per i fogli di stile
web/js/
per i Javascript. Questa è una delle convenzioni definite da symfony,
ma potete salvarli ovunque vogliate all'interno della cartella web/
.
Il lettore più attento avrà notato che anche se il file main.css
non è
menzionato in nessun posto nel layout, è presente nell'HTML generato. Ma nessun
altro file è presente. Com'è possibile?
Il foglio di stile è stato incluso dalla funzione ~include_stylesheets~()
chiamata nel tag <head>
all'interno del layout. La funzione include_stylesheets()
è chiamata helper. Un helper è una funzione definita da symfony, che accetta
dei parametri e restituisce codice HTML. La maggior parte delle volte, gli helper
fanno risparmiare del tempo e racchiudono degli spezzoni di codice usati di
frequente nei template. L'helper include_stylesheets()
genera il tag <link>
per i fogli di stile.
Ma come fa l'helper a sapere quali fogli di stile includere?
Lo strato della Vista può essere configurato modificando il file di configurazione
dell'applicazione view.yml
. Questo è quello generato di default dal comando
generate:app
:
# 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: true layout: layout
Il file view.yml
configura le impostazioni di default
per ogni template
dell'applicazione. Per esempio, l'elemento stylesheets
definisce un array di
fogli di stile da includere in ogni pagina dell'applicazione (l'inclusione è
fatta dall'helper include_stylesheets()
).
note
Nel file view.yml
di default, il file referenziato è main.css
e non
/css/main.css
. Comunque, le due definizioni sono equivalente in quanto
symfony aggiunge il prefisso /~css~/
ai percorsi relativi.
Se molti file sono definiti, symfony li includerà nello stesso ordine della definizione:
stylesheets: [main.css, jobs.css, job.css]
Si può anche cambiare l'attributo media
e omettere il suffisso .css
:
stylesheets: [main.css, jobs.css, job.css, print: { media: print }]
Questo file di configurazione sarà tradotto in:
<link rel="stylesheet" type="text/css" media="screen" href="/css/main.css" /> <link rel="stylesheet" type="text/css" media="screen" href="/css/jobs.css" /> <link rel="stylesheet" type="text/css" media="screen" href="/css/job.css" /> <link rel="stylesheet" type="text/css" media="print" href="/css/print.css" />
tip
Il file di configurazione view.yml
definisce anche il layout usato dall'applicazione.
Di default, il nome è layout
, così symfony decora ogni pagina con il file
layout.php
. Si può anche disabilitare il processo di decorazione una volta per
tutte, impostando la proprietà has_layout
a false
.
Funziona già così com'è, ma il file jobs.css
è necessario solo per l'homepage,
e il file job.css
è necessario solo per la pagina del lavoro. Il file view.yml
può essere personalizzato in ogni modulo. Cambiamo la chiave stylesheets
del file view.yml
dell'applicazione in modo che contenga solo il file main.css
:
# apps/frontend/config/view.yml stylesheets: [main.css]
Per personalizzare la vista del modulo job
, creiamo un file view.yml
all'interno della cartella apps/frontend/modules/job/config
:
# apps/frontend/modules/job/config/view.yml indexSuccess: stylesheets: [jobs.css] showSuccess: stylesheets: [job.css]
All'interno delle sezioni indexSuccess
e showSuccess
(sono i nomi dei file dei
template associati alle azioni index
e show
, come vedremo in seguito), si può
personalizzare ogni elemento all'interno della sezione default
del file
view.yml
dell'applicazione. Tutti i nuovi elementi sono sostituiti a quelli
definiti nella configurazione dell'applicazione. Si possono inoltre definire alcune
configurazioni per tutte le azioni di un modulo con la sezione speciale all
.
Solitamente, quando qualcosa è configurabile tramite un file di configurazione,
lo è anche tramite codice PHP. al posto di create un file view.yml
per il modulo
job
per esempio, potete anche usare l'helper ~use_stylesheet~()
per includere
un foglio di stile da un template:
<?php use_stylesheet('main.css') ?>
Si può anche usare questo helper nel layout per includere un foglio di stile globale.
Scegliere tra un metodo è l'altro è solo un questione di gusti. Il file view.yml
fornisce un modo per definire impostazioni per tutte le azioni di un modulo,
che non è possibile in un template, ma la configurazione è statica. D'altro canto,
usare l'helper use_stylehseet()
è più flessibile e, soprattutto, è tutto nello
stesso posto: la definizione dello stile e il codice HTMl. Per Jobeet useremo
l'helper use_stylesheet()
, per cui potete eliminare il file view.yml
che
abbiamo appena creato e modificare i template job
con le chiamate a use_stylesheet()
:
<!-- apps/frontend/modules/job/templates/indexSuccess.php --> <?php use_stylesheet('jobs.css') ?> <!-- apps/frontend/modules/job/templates/showSuccess.php --> <?php use_stylesheet('job.css') ?>
note
Simmetricamente, la configurazione di Javascript è eseguita dell'elemento javascripts
del file view.yml
e l'helper ~use_javascript~()
definisce i file JavaScript
da includere in un template.
L'Homepage di Jobeet
Come visto nel giorno 3, la pagina dei lavori è generata dall'azione index
del
modulo job
. L'azione index
è la parte Controller della pagina e il template
associato, indexSuccess.php
, è la View:
apps/ frontend/ modules/ job/ actions/ actions.class.php templates/ indexSuccess.php
L'azione
Ogni azione è rappresentata da un metodo di una classe. Per l'homepage di Jobeet,
la classe è jobActions
(il nome del modulo seguito dal suffisso Actions
) ed
il metodo è executeIndex()
(execute
seguito dal nome dell'azione).
L'azione recupera tutti i lavori dal database:
// apps/frontend/modules/job/actions/actions.class.php class jobActions extends sfActions { public function executeFooBar(sfWebRequest $request) { $this->jobeet_jobs = JobeetJobPeer::doSelect(new Criteria()); } // ... }
Diamo uno sguardo da vicino al codice: il metodo executeIndex()
(il Controllore)
chiama il Modello JobeetJobPeer
per recuperare tutti i lavori (new Criteria()
).
Esso restituisce un array di oggetti JobeetJob
che sono assegnati alla
proprietà jobeet_jobs
.
Ognuna di queste proprietà è automaticamente passata al template (la Vista). Per
passare dati dal Controllore alla Vista, basta creare una nuova proprietà:
public function executeIndex(sfWebRequest $request) { $this->foo = 'bar'; $this->bar = array('bar', 'baz'); }
Questo codice renderà le variabili $foo
e $bar
accessibili dal template.
Il Template
Di default, il template associato a un'azione è dedotto da symfony grazie a
una convenzione (il nome dell'azione seguito dal suffisso Success
).
Il template indexSuccess.php
genera una tabella HTML per tutti i lavori.
Ecco il codice attuale del template:
<!-- apps/frontend/modules/job/templates/indexSuccess.php --> <?php use_stylesheet('jobs.css') ?> <h1>Job List</h1> <table> <thead> <tr> <th>Id</th> <th>Category</th> <th>Type</th> <!-- more columns here --> <th>Created at</th> <th>Updated at</th> </tr> </thead> <tbody> <?php foreach ($jobeet_jobs as $jobeet_job): ?> <tr> <td> <a href="<?php echo url_for('job/show?id='.$jobeet_job->getId()) ?>"> <?php echo $jobeet_job->getId() ?> </a> </td> <td><?php echo $jobeet_job->getCategoryId() ?></td> <td><?php echo $jobeet_job->getType() ?></td> <!-- more columns here --> <td><?php echo $jobeet_job->getCreatedAt() ?></td> <td><?php echo $jobeet_job->getUpdatedAt() ?></td> </tr> <?php endforeach; ?> </tbody> </table> <a href="<?php echo url_for('job/new') ?>">New</a>
Nel codice del template, il foreach
scorre attraverso la lista di oggetti Job
($jobeet_jobs
) e, per ognuno di loro, ogni valore delle colonne è visualizzato.
Ricordate che accedere al valore di una colonna è semplice come chiamare un metodo getter,
il cui nome inizia con get
ed è seguito dal nome della colonna in formato
camelCase (per esempio il metodo getCreatedAt()
per la colonna created_at
).
Ripuliamolo un po', per visualizzare solo un sottoinsieme di colonne disponibili:
<!-- apps/frontend/modules/job/templates/indexSuccess.php --> <?php use_stylesheet('jobs.css') ?> <div id="jobs"> <table class="jobs"> <?php foreach ($jobeet_jobs as $i => $job): ?> <tr class="<?php echo fmod($i, 2) ? 'even' : 'odd' ?>"> <td><?php echo $job->getLocation() ?></td> <td> <a href="<?php echo url_for('job/show?id='.$job->getId()) ?>"> <?php echo $job->getPosition() ?> </a> </td> <td><?php echo $job->getCompany() ?></td> </tr> <?php endforeach; ?> </table> </div>
La funzione url_for()
in questo template è un helper che verrà discusso domani.
Il template della pagina del lavoro
Personalizziamo ora il template della pagina del lavoro. Apriamo il file showSuccess.php
e sostituiamo il suo contenuto con il codice seguente:
<!-- apps/frontend/modules/job/templates/showSuccess.php --> <?php use_stylesheet('job.css') ?> <?php use_helper('Text') ?> <div id="job"> <h1><?php echo $job->getCompany() ?></h1> <h2><?php echo $job->getLocation() ?></h2> <h3> <?php echo $job->getPosition() ?> <small> - <?php echo $job->getType() ?></small> </h3> <?php if ($job->getLogo()): ?> <div class="logo"> <a href="<?php echo $job->getUrl() ?>"> <img src="/uploads/jobs/<?php echo $job->getLogo() ?>" alt="<?php echo $job->getCompany() ?> logo" /> </a> </div> <?php endif; ?> <div class="description"> <?php echo simple_format_text($job->getDescription()) ?> </div> <h4>How to apply?</h4> <p class="how_to_apply"><?php echo $job->getHowToApply() ?></p> <div class="meta"> <small>posted on <?php echo $job->getCreatedAt('m/d/Y') ?></small> </div> <div style="padding: 20px 0"> <a href="<?php echo url_for('job/edit?id='.$job->getId()) ?>">Edit</a> </div> </div>
Questo template usa la variabile $job
, passata dall'azione, per mostrare l'informazione
sul lavoro. Poiché abbiamo rinominato la variabile passata al template da $jobeet_job
a
$job
, dobbiamo riportare questo cambiamento nell'azione show
(attenzione, ci
sono due occorrenze della variabile):
// apps/frontend/jobeet/actions/actions.class.php public function executeShow(sfWebRequest $request) { $this->job = JobeetJobPeer::retrieveByPk($request->getParameter('id')); $this->forward404Unless($this->job); }
Notate che alcuni metodi di Propel accettano dei parametri. Siccome abbiamo definito la
colonna created_at
come un timestamp, il metodo getCreatedAt()
accetta uno schema di
formattazione della data come primo parametro.
$job->getCreatedAt('m/d/Y');
note
La descrizione del lavoro usa l'helper simple_format_text()
per formattarsi come HTML,
sostituendo ad esempio gli "a capo" con un <br />
. Poiché tale helper appartiene al
gruppo di helper Text
, che non è caricato di default, l'abbiamo caricato manualmente
usando l'helper ~use_helper~()
.
Gli slot
Ed ora, il titolo di tutte le pagine è definito nel tag <title>
del layout:
<title>Jobeet - Your best job board</title>
Ma per la pagina del lavoro vogliamo fornire delle informazioni più dettagliate, come il nome della compagnia e la posizione del lavoro.
In symfony, quando una zona del layout dipende dal template che deve essere visualizzato, occorre definire uno slot:
Aggiungiamo uno slot al layout per avere un titolo dinamico:
// apps/frontend/templates/layout.php <title><?php include_slot('title') ?></title>
Ogni slot è definito da un nome (title
) e può essere visualizzato usando l'helper
~include_slot~()
. Ora, all'inizio del template showSuccess.php
, usiamo l'helper
slot()
per definire il contenuto dello slot per la pagina del lavoro:
// apps/frontend/modules/job/templates/showSuccess.php <?php slot('title', sprintf('%s is looking for a %s', $job->getCompany(), $job->getPosition())) ?>
Se il titolo è complesso da generare, l'helper slot()
può anche essere usato con un
blocco di codice:
// apps/frontend/modules/job/templates/showSuccess.php <?php slot('title') ?> <?php echo sprintf('%s is looking for a %s', $job->getCompany(), $job->getPosition()) ?> <?php end_slot(); ?>
Per alcune pagine, come la homepage, ci serve solo un titolo generico. Invece di ripetere lo stesso titolo più e più volte nei template, possiamo definire un titolo di default nel layout:
// apps/frontend/templates/layout.php <title> <?php include_slot('title', 'Jobeet - Your best job board') ?> </title>
Il secondo parametro del metodo include_slot()
è il valore predefinito per
lo slot se non è stato definito. Se il valore predefinito è lungo o ha
alcuni tag HTML, si può anche crearlo come mostrato nel seguente codice:
// apps/frontend/templates/layout.php <title> <?php if (!include_slot('title')): ?> Jobeet - Your best job board <?php endif; ?> </title>
L'helper include_slot()
restituisce true
se lo slot è stato definito. Quindi, se
abbiamo definito uno slot title
in un template, verrà usato; altrimenti, verrà usato
il titolo di default.
tip
Abbiamo già visto alcuni helper che iniziano con include_
. Questi helper
visualizzano l'HTML e in molti casi hanno una controparte get_
, per restituire
solamente il contenuto:
<?php include_slot('title') ?> <?php echo get_slot('title') ?> <?php include_stylesheets() ?> <?php echo get_stylesheets() ?>
L'azione della pagina del lavoro
La pagina del lavoro è generata dall'azione show
, definita nel metodo executeShow()
del modulo job
:
class jobActions extends sfActions { public function executeShow(sfWebRequest $request) { $this->job = JobeetJobPeer::retrieveByPk($request->getParameter('id')); $this->forward404Unless($this->job); } // ... }
Come nell'azione index
, la classe JobeetJobPeer
è usata per recuperare un
lavoro, stavolta usando il metodo retrieveByPk()
. Il parametro di questo metodo
è l'identificatore univoco di un lavoro, la sua chiave primaria. La prossima sezione
spiegherà perché l'istruzione $request->getParameter('id')
restituisce la chiave
primaria del lavoro.
tip
Le classi del modello generate contengono molti metodi utili per interagire
con gli oggetti del progetto. Prendetevi un po' di tempo per analizzare il codice
che si trova nella cartella lib/om/
e per scoprire la potenza nascosta
in queste classi.
Se il lavoro non esiste nel database, vogliamo rimandare l'utente a una pagina 404,
che è esattamente ciò che fa il metodo forward404Unless()
. Questo accetta un
booleano come primo parametro e, a meno che non sia vero, ferma il flusso corrente
dell'esecuzione. Poiché i metodi "forward" fermano l'esecuzione dell'azione
sollevando un'eccezione sfError404Exception
, non si ha bisogno di usare return
successivamente.
Come per le eccezioni, la pagina mostrata all'utente è diversa negli ambienti
prod
e dev
:
note
Prima di pubblicare il sito Jobeet su un server di produzione, impareremo a personalizzare la pagina 404 di default.
La richiesta e la risposta
Quando si visitano le pagine /job
o /job/show/id/1
nel proprio browser, si
dà inizio a un viaggio nel server web. Il browser invia una richiesta e il
server rimanda indietro una risposta.
Abbiamo già visto che symfony incapsula la richiesta in un oggetto sfWebRequest
(si veda il metodo executeShow()
). E siccome symfony è un framework orientato
agli oggetti, anche la risposta è un oggetto, della classe sfWebResponse
.
Si può accedere all'oggetto risposta in un'azione richiamando $this->getResponse()
.
Questi oggetti forniscono molti metodi utili per accedere alle informazioni dalle funzioni e dalle variabili globali di PHP.
note
Perché symfony ha un wrap di funzionalità esistenti in PHP? Innanzitutto,
perché i metodi di symfony sono più potenti delle controparti PHP. Poi, perché
quando si testa un'applicazione, è più facile simulare un oggetto richiesta o
risposta piuttosto che trattare variabili globali o usare funzioni come
header()
, che fanno troppe cose di nascosto.
La richiesta
La classe sfWebRequest
è un wrapper per le array globali di PHP $_SERVER
,
$_COOKIE
, $_GET
, $_POST
e $_FILES
Nome del metodo | Equivalente 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_REQUESTED_WITH'] == 'XMLHttpRequest' |
getHttpHeader() |
$_SERVER |
getCookie() |
$_COOKIE |
isSecure() |
$_SERVER['HTTPS'] |
getFiles() |
$_FILES |
getGetParameter() |
$_GET |
getPostParameter() |
$_POST |
getUrlParameter() |
$_SERVER['PATH_INFO'] |
getRemoteAddress() |
$_SERVER['REMOTE_ADDR'] |
Abbiamo già avuto accesso ai parametri della richiesta usando il metodo
getParameter()
. Esso restituisce un valore dalla variabile globale $_GET
o $_POST
, oppure dalla variabile PATH_INFO
.
Se si vuole essere certi che un parametro della richiesta venga da una
particolare di queste variabili, si devono usare rispettivamente i metodi
getGetParameter()
, getPostParameter()
e getUrlParameter()
.
note
Se si vuole limitare un'azione per un metodo HTTP specifico, ad esempio se si
vuole essere sicuri che una form sia inviata come POST
, si può usare
il metodo isMethod()
: $this->forwardUnless($request->isMethod('POST'));
.
La risposta
La classe sfWebResponse
è un wrapper per le funzioni PHP ~header~()
e setraw~cookie~()
:
Nome del metodo | Equivalente PHP |
---|---|
setCookie() |
setrawcookie() |
setStatusCode() |
header() |
setHttpHeader() |
header() |
setContentType() |
header() |
addVaryHttpHeader() |
header() |
addCacheControlHttpHeader() |
header() |
Ovviamente, la classe sfWebResponse
fornisce anche un modo per impostare il
contenuto della risposta (setContent()
) e inviare la risposta al browser
(send()
).
In questo giorno abbiamo visto come gestire i fogli di stile e i JavaScript
sia nel file view.yml
che nei template. Alla fine, entrambe le tecniche
usano i metodi dell'oggetto risposta addStylesheet()
e addJavascript()
.
tip
Le classi sfAction
, sfRequest
e sfResponse
forniscono molti altri
metodi utili. Non esitate a consultare la
documentazione delle API per saperne
di più su tutte le classi interne di symfony.
A domani
Oggi abbiamo descritto alcuni design pattern usati da symfony. Speriamo che ora la struttura delle cartelle abbia più senso. Abbiamo giocato coi template, manipolando il layout e i file dei template. Li abbiamo anche resi un po' più dinamici, grazie agli slot e alle azioni.
Domani impareremo di più sull'helper url_for()
che abbiamo usato oggi,
e sul sub-framework del routing associato con esso.
This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License license.