Development

Documentation/it_IT/book/1.1/16-Application-Management-Tools (diff)

You must first sign up to be able to contribute.

Changes from Version 1 of Documentation/it_IT/book/1.1/16-Application-Management-Tools

Show
Ignore:
Author:
garak (IP: 85.18.214.242)
Timestamp:
10/31/08 17:10:18 (9 years ago)
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Documentation/it_IT/book/1.1/16-Application-Management-Tools

    v0 v1  
     1{{{ 
     2#!WikiMarkdown  
     3 
     4Capitolo 16 - Strumenti di gestione delle applicazioni 
     5====================================================== 
     6 
     7Sia durante la fase di sviluppo che durante quella di distribuzione gli sviluppatori hanno bisogno di strumenti di diagnostica per verificare che l'applicazione funzioni come ci si aspetta. Tale informazioni sono generalmente aggregate tramite utility di log e di debug. A causa del ruolo centrale che il framework (come symfony) gioca nello sviluppo, è importante che tali strumenti siano strettamente integrati. 
     8 
     9Durante la vita di un'applicazione sul server di produzione, l'amministratore opera ripetutamente una grande quantità di operazioni, dalla rotazione dei log agli upgrade. Un framework dovrebbe fornire anche strumenti per automatizzare il più possibile tali task. 
     10 
     11Questo capitolo spiega come gli strumenti di gestione delle applicazioni di symfony aiutano a soddisfare tali bisogni. 
     12 
     13 
     14Logging 
     15------- 
     16 
     17L'unico modo per capire cosa è andato storto durante l'esecuzione di una richiesta è controllare le tracce dell'esecuzione del processo. Fortunatamente, come imparerai in questa sezione, sia PHP che symfony tendono ad immagazzinare una grande quantità di dati di questo tipo. 
     18 
     19 
     20### Log di PHP 
     21 
     22PHP possiede un parametro chiamato `error_reporting` definito in `php.ini`, che specifica quali eventi PHP devono essere loggati. Symfony ti permette di fare l'override di tale valore, sia per applicazione che per ambiente, nel file `settings.yml`, come mostrato nel Listato 16-1. 
     23 
     24Listato 16-1 - Impostare il livello di reporting degli errori, in `frontend/config/settings.yml` 
     25 
     26    prod: 
     27     .settings: 
     28        error_reporting:  <?php echo (E_PARSE | E_COMPILE_ERROR | E_ERROR | E_CORE_ERROR | E_USER_ERROR)."\n" ?> 
     29     
     30    dev: 
     31      .settings: 
     32        <?php echo (E_ALL | E_STRICT)."\n" ?> 
     33 
     34Per evitare problemi di prestazioni nell'ambiente di produzione, il server logga solo gli errori PHP critici. Nell'ambiente di sviluppo, invece, tutti gli eventi vengono loggati, in modo che lo sviluppatore abbia tutte le informazioni necessarie per rintracciare errori. 
     35 
     36Puoi trovare i file dei log di PHP a seconda di come hai configurato il tuo `php.ini`. Se non hai mai cambiato la configurazione di default, probabilmente PHP usa i log del web server (come quelli di Apache). In tal caso, troverai i file nella cartella di log del web server. 
     37 
     38<b>Nuovo in symfony 1.1</b>: Il formato dei file di log ora è configurabile sovrascrivendo le impostazioni `format` e/o  `time_format` in `factories.yml`, come mostrato nel Listato 16-3. 
     39 
     40Listato 16-3 - Cambiare il formato dei log 
     41 
     42    all: 
     43      logger: 
     44        param: 
     45          sf_file_debug: 
     46            format:      %time% %type% [%priority%] %message%%EOL% 
     47            time_format: %b %d %H:%M:%S 
     48 
     49### Configurazione del livello di log di symfony 
     50 
     51In aggiunta ai log standard di PHP, symfony può tenere traccia di molti eventi personalizzati. Puoi trovare tutti i log di symfony nella cartella `myproject/log/`. C'è un file per applicazione e ambiente. Ad esempio, il file di log per l'ambiente di sviluppo dell'applicazione `frontend` si chiama `frontend_dev.log`, mentre quello per l'ambiente di produzione si chiama `frontend_prod.log`, e così via. 
     52 
     53Se stai facendo girare un'applicazione symfony, dai un'occhiata ai suoi file di log. La sintassi è molto semplice. Per ogni evento viene aggiunta una linea al file dell'applicazione. Ogni linea include l'ora esatta dell'evento, la sua natura, l'oggetto che viene processato, e qualche altro dettaglio importante. Il Listato 16-2 ne mostra un esempio. 
     54 
     55Listato 16-2 - Esempio di file di log di symfony, in `log/frontend_dev.php` 
     56    [php] 
     57    Nov 15 16:30:25 symfony [info ] {sfAction} call "barActions->executemessages()" 
     58    Nov 15 16:30:25 symfony [debug] SELECT bd_message.ID, bd_message.SENDER_ID, bd_... 
     59    Nov 15 16:30:25 symfony [info ] {sfCreole} executeQuery(): SELECT bd_message.ID... 
     60    Nov 15 16:30:25 symfony [info ] {sfView} set slot "leftbar" (bar/index) 
     61    Nov 15 16:30:25 symfony [info ] {sfView} set slot "messageblock" (bar/mes... 
     62    Nov 15 16:30:25 symfony [info ] {sfView} execute view for template "messa... 
     63    Nov 15 16:30:25 symfony [info ] {sfView} render "/home/production/myproject/... 
     64    Nov 15 16:30:25 symfony [info ] {sfView} render to client 
     65 
     66Puoi trovare molti dettagli in questi file, incluse le query effettivamente spedite al db, le template chiamate, le catene di chiamate tra gli oggetti e così via. 
     67 
     68 
     69#### Configurazione dei livelli di log di symfony 
     70 
     71Esistono otto livelli per i messaggi di log di symfony: `emerg, alert, crit, err, warning, notice, info`, e `debug`, che sono gli stessi livelli del pacchetto `PEAR::Log` ([http://pear.php.net/package/Log/]). Puoi definire il massimo livello da loggare per ogni ambiente nel file di configurazione `factories.yml` di ogni applicazione, come mostrato nel Listato 16-4. 
     72 
     73Listato 16-4 - Configurazione di default del logging, in `frontend/config/logging.yml` 
     74 
     75    prod: 
     76      logger: 
     77        param: 
     78          level: err 
     79 
     80Per default, in tutti gli ambienti tranne quello di produzione, tutti gli eventi vengono loggati (fino al minimo importante, il livello `debug`). Nell'ambiente di produzione, il logging è disabilitato per default; se imposti `enabled` a `on`, appariranno nel logo solo i messaggi più importanti (da `crit` a `emerg`). 
     81 
     82Puoi cambiare il livello di logging nel file `factories.yml` per ogni ambiente per limitare il tipo di messaggi da loggare. 
     83 
     84>**TIP** 
     85>Per controllare se il logging è abilitato, richiama `sfConfig::get('sf_ logging_enabled')`. 
     86 
     87#### Aggiungere un messaggio di log 
     88 
     89Puoi aggiungere un messaggio nei file di log di symfony usando una delle tecniche descritte nel Listato 16-5. 
     90 
     91Listato 16-5 - Aggiungere un messaggio di log personalizzato 
     92 
     93    [php] 
     94    // Da un'azione 
     95    $this->logMessage($message, $level); 
     96     
     97    // Da una template 
     98    <?php use_helper('Debug') ?> 
     99    <?php log_message($message, $level) ?> 
     100 
     101Alternativamente, per scrivere un messaggio di log da un qualsiasi punto della tua applicazione, usa il metodo `sfLogger` direttamente, come mostrato nel Listato 16-6. I metodi disponibili prendono lo stesso nome dei livelli di log. 
     102 
     103Listato 16-6 - Aggiungere un messaggio di log da un qualsiasi punto 
     104 
     105    [php] 
     106    if (sfConfig::get('sf_logging_enabled')) 
     107    { 
     108      sfContext::getInstance()->getLogger()->info($message); 
     109    } 
     110 
     111>**SIDEBAR** 
     112>Nuovo in symfony 1.1: Personalizzare il logging 
     113> 
     114>Il sistema di logging di symfony è molto semplice, per cui è anche semplice personalizzarlo. Il solo prerequisito è che la classe di log estenda la classe `sfLogger`, che definisce il metodo `doLog()`. Symfony richiama il metodo `doLog()` con due parametri: `$message` (il messaggio da loggare) e `$priority` (il livello di log) 
     115> 
     116>La classe `myLogger` definisce un semplice logger che usa la funzione PHP `error_log`: 
     117> 
     118>    class myLogger extends sfLogger 
     119>    { 
     120>      protected function doLog($message, $priority) 
     121>      { 
     122>        error_log(sprintf('%s (%s)', $message, sfLogger::getPriorityName($priority))); 
     123>      } 
     124>    } 
     125> 
     126>Per creare un logger da una classe esistente, basta implementare l'interfaccia `sfLoggerInterface`, che definisce un metodo `log()`. Il metodo accetta gli stessi parametri del metodo `doLog()`: 
     127> 
     128>    require_once('Log.php'); 
     129>    require_once('Log/error_log.php'); 
     130>      
     131>    // Definisce un piccolo contenitore che implementa l'interfaccia 
     132>    // per il logger che vogliamo usare con symfony 
     133>    class Log_my_error_log extends Log_error_log implements sfLoggerInterface 
     134>    { 
     135>    } 
     136 
     137#### Pulire e ruotare i file di log 
     138 
     139Non dimenticare di pulire periodicamente la cartella `log/` delle tue applicazioni, perché tali file hanno la strana abitudine di crescere di diversi megabyte al giorno, in relazione, ovviamente, al traffico. A tale scopo symfony fornisce un task `log-purge`, che puoi lanciare a mano od impostare in una tabella di cron. Ad esempio, il comando seguente elimina i file di log delle applicazioni in cui è specificato `purge: on` nel file `logging.yml` (che è il default): 
     140 
     141    > php symfony log:clear 
     142     
     143Sia per le prestazioni che per la sicurezza, probabilmente vorrai tenere i log di symfony in diversi piccoli file piuttosto che in un unico file di grandi dimensioni. La strategia di storage dei file di log ideale è di fare il backup per poi svuotare il file di log regolarmente, ma di mantenere un numero limitato di file di backup. Puoi abilitare questo tipo di rotazione e specificarne i parametri nel file `logging.yml`. Ad esempio, con un `period` di 7 giorni ed una `history` (numero di backup) di 10, come mostrato nel Listato 16-7, lavoreresti con un file di log attivo più 10 backup contenenti ognuno 7 giorni di log. 
     144 
     145Listato 16-7 - Lanciare la rotazione dei log 
     146 
     147    > php symfony log:rotate frontend prod --period=7 --history=10 
     148 
     149Il backup dei file di log viene tenuto nella cartella `logs/history/`, con un suffisso che indica la data in cui è stato fatto il backup. 
     150 
     151Debugging 
     152--------- 
     153 
     154Non ha importanza quanto sei bravo nello sviluppo, prima o poi, anche se usi symfony, qualche errore lo commetterai. Trovare e capire gli errori è una delle chiavi dello sviluppo veloce di un'applicazione. Fortunatamente, symfony mette a disposizione diversi strumenti di debugging per lo sviluppatore. 
     155 
     156### Modalità di debug 
     157 
     158Symfony possiede una modalità di debug per facilitare lo sviluppo ed il debug delle applicazioni. Quando è attivo, succede questo: 
     159 
     160  * La configurazione viene controllata ad ogni richiesta, per cui qualsiasi cambiamento non richiede la pulizia della cache. 
     161  * I messaggi di errore vengono visualizzati in modo chiaro ed utile, in modo che si possa trovare immediatamente il "colpevole". 
     162  * Sono disponibili strumenti di debugging ulteriori quali ad esempio i dettagli delle query al db. 
     163  * Anche la modalità di debug di Propel viene attivata, per cui qualsiasi errore in una chiamata Propel visualizzerà dettagliatamente la catena delle chiamate tramite l'architettura Propel. 
     164 
     165D'altra parte, quando la modalità di debug non è attiva, il processo è gestito nel modo seguente: 
     166 
     167  * I file di configurazione YAML vengono processati una volta sola, e poi trasformati in file PHP nella cartella `cache/config/`. Ogni richiesta successiva alla prima ignora i file YAML e consulta quelli in cache. Di conseguenza, il processo delle richieste è molto più veloce. 
     168  * Per permettere nuovamente la consultazione dei file di configurazione, occorre pulire la cache. 
     169  * Un errore durante l'esecuzione genera un codice 500 (Internal Server Error), senza alcune spiegazioni sulle cause. 
     170 
     171La modalità di debug viene attivata per applicazione nel front controller. È controllata dal valore della costante `SF_DEBUG`, come mostrato nel Listato 16-8. 
     172 
     173Listato 16-8 - Esempio di front controller con la modalità di debug attiva, in `web/frontend_dev.php` 
     174    [php] 
     175    require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php'); 
     176      
     177    $configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'dev', true); 
     178    sfContext::createInstance($configuration)->dispatch(); 
     179 
     180>**CAUTION** 
     181>Non dovresti attivare la modalità di debug sul server di produzione, e neppure lasciare la possibilità di farlo. Non solo peggiorerebbe le prestazioni, ma potrebbe anche rivelare le interna della tua applicazione, mettendone a rischio la sicurezza. 
     182 
     183### Le eccezioni di symfony 
     184 
     185Quando capita un'eccezione in modalità di debug, symfony mostra un insieme di informazioni interessanti che aiutano a capire la causa del problema. 
     186 
     187I messaggi di eccezione sono scritti chiaramente e si riferiscono alla causa più probabile del problema. Spesso suggeriscono anche una soluzione al problema, e per quelli più comuni c'è un link alla pagina del sito di symfony con maggiori dettagli sull'eccezione generata. Tramite la syntax highlighting viene mostrato il tratto di codice PHP che ha generato l'eccezione, e l'insieme delle chiamate ai metodi, come mostrato in Figura 16-1. Vengono mostrati anche gli argomenti passati ai metodi. 
     188 
     189>**NOTE** 
     190>Symfony si basa veramente sulle eccezioni PHP per il report degli errori, che è molto meglio rispetto al modo in cui lavora PHP 4. Ad esempio, un errore 404 può essere triggerato tramite `sfError404Exception`. 
     191 
     192Figura 16-1 - Esempio di eccezione di un'applicazione symfony 
     193 
     194![Esempio di eccezione di un'applicazione symfony](http://www.symfony-project.org/images/book/1_1/F1601.png "Esempio di eccezione di un'applicazione symfony") 
     195 
     196Durante la fase di sviluppo, le eccezioni symfony saranno di grande utilità per il debug. 
     197 
     198### L'estensione Xdebug 
     199 
     200L'estensione Xdebug ([http://xdebug.org/](http://xdebug.org/)) permette di estendere le informazioni che vengono loggate dal web server. Symfony integra i messaggi di Xdebug nel proprio feedback, per cui è una buona idea attivare tale estensione durante il debug di un'applicazione. L'installazione dell'estensione dipende molto dalla piattaforma; consulta il sito di Xdebug per informazioni dettagliate al riguardo. Una volta che hai installato Xdebug, lo devi attivare nel file `php.ini`. Per le piattaforme *nix, questo si può fare aggiungendo la linea: 
     201 
     202    zend_extension="/usr/local/lib/php/extensions/no-debug-non-zts-20041030/xdebug.so" 
     203 
     204mentre per le piattaforme Windows: 
     205 
     206    extension=php_xdebug.dll 
     207 
     208Il Listato 16-9 mostra un esempio di configurazione di Xdebug, quale deve essere aggiunto nel file `php.ini`. 
     209 
     210Listato 16-9 - Esempio di configurazione Xdebug 
     211 
     212    ;xdebug.profiler_enable=1 
     213    ;xdebug.profiler_output_dir="/tmp/xdebug" 
     214    xdebug.auto_trace=1             ; enable tracing 
     215    xdebug.trace_format=0 
     216    ;xdebug.show_mem_delta=0        ; memory difference 
     217    ;xdebug.show_local_vars=1 
     218    ;xdebug.max_nesting_level=100 
     219 
     220Per poterla attivare devi infine riavviare il tuo web server. 
     221 
     222>**CAUTION** 
     223>Non dimenticare di disattivare Xdebug sul tuo sistema in produzione. Altrimenti la velocità di esecuzione delle pagine ne soffrirà molto. 
     224 
     225### La toolbar Web Debug 
     226 
     227I file di log contengono informazioni interessanti, ma non sono molto facili da leggere. Il compito più semplice, ovvero trovare le linee loggate per una richiesta particolare, può risultare difficoltoso se diversi utenti usano l'applicazione nello stesso momento e l'history del log è lunga. Ecco quando la web debug toolbar diventa utile. 
     228 
     229Questa toolbar appare come un rettangolo semitrasparente nell'angolo in alto a destra del browser, come mostrato in Figura 16-2. Essa fornisce accesso agli eventi di log di symfony, alla configurazione corrente, alle proprietà della richiesta e gli oggetti della risposta, ai dettagli delle query eseguite sul db ed alle prestazioni. 
     230 
     231Figura 16-2 - La web debug toolbar appare sull'angolo in alto a destra 
     232 
     233![La web debug toolbar appare sull'angolo in alto a destra](http://www.symfony-project.org/images/book/1_1/F1602.jpg "La web debug toolbar appare sull'angolo in alto a destra") 
     234 
     235Il colore del background della toolbar dipende dal più alto livello dei messaggi di log durante la richiesta. Se non vi è alcun messaggio a livello debug, la toolbar rimane grigia. Se anche un solo messaggio raggiunge il livello `err`, la toolbar diventa rossa. 
     236 
     237>**NOTE** 
     238>Non confondere la modalità di debug con la debug toolbar. Essa può essere visualizzata anche quando la modalità di debug è `off`, anche se in quel caso mostra molte meno informazioni. 
     239 
     240Per attivare la web debug toolbar per un'applicazione, apri il file `settings.yml` e cerca la chiave `web_debug`. Negli ambienti `prod` e `test`, il suo valore di default è `off`, per cui se la desideri la devi attivare manualmente. Nell'ambiente `dev`, il valore di default è `on`, come mostrato nel Listato 16-10. 
     241 
     242Listato 16-10 - Attivazione della web debug toolbar, in `frontend/config/settings.yml` 
     243 
     244    dev: 
     245      .settings: 
     246        web_debug:              on 
     247 
     248Quando visualizzata, la toolbar offre una grande varietà di informazioni/interazioni: 
     249 
     250  * Clicca sul logo di symfony per nasconderla; quando è nascosta, non copre gli elementi in quell'area della pagina. 
     251  * Clicca la sezione `vars & config` per vedere i dettagli della richiesta, risposta, impostazioni e variabili PHP, come mostrato in Figura 16-3. La prima linea riassume le impostazioni più importanti della configurazione, come la modalità di debug, la cache, e la presenza di un acceleratore PHP (essi appaiono in rosso se disattivati, in verde se attivi). 
     252 
     253Figura 16-3 - La sezione vars & config mostra tutte le variabili e costanti della richiesta 
     254 
     255![La sezione vars & config mostra tutte le variabili e costanti della richiesta](http://www.symfony-project.org/images/book/1_1/F1603.png "La sezione vars & config mostra tutte le variabili e costanti della richiesta") 
     256 
     257 
     258  * Quando la cache è abilitata, appare una freccia verde nella toolbar. Clicca tale freccia per riprocessare la pagina, ignorando la cache (la quale però non viene svuotata). 
     259  * Clicca su `logs & msg` per vedere le informazioni dei file di log della richiesta corrente, come mostrato in Figura 16-4. A seconda dell'importanza degli eventi, esse saranno visualizzate in grigio, giallo o rosso. Puoi filtrare gli eventi visualizzati usando i link all'inizio della lista. 
     260 
     261Figura 16-4 - La sezione logs & msg mostra i log per la richiesta corrente 
     262 
     263![La sezione logs & msg mostra i log per la richiesta corrente](http://www.symfony-project.org/images/book/1_1/F1604.png "La sezione logs & msg mostra i log per la richiesta corrente") 
     264 
     265>**NOTE** 
     266>Quando l'azione corrente è il risultato di un redirect, saranno presenti nel pannello solo i log dell'ultima richiesta, per cui i file di log sono ancora indispensabili per un buon debug. 
     267 
     268  * Per le richieste che eseguono query SQL, nella toolbar appare l'icona di un database. Cliccala per vedere i dettagli delle query, come mostrato in Figura 16-5. 
     269  * Alla destra dell'orologio c'è il tempo totale necessario a processare la richiesta. Ricorda che la web debug toolbar e la modalità di debug rallentano l'esecuzione delle richieste, per cui evita di considerare tali valori in se e confronta l'esecuzione fra due pagine. Clicca sull'orologio per vedere i dettagli del tempo di processione per categoria, come mostrato in Figura 16-6. Symfony visualizza il tempo speso su parti specifiche della richiesta. Solo i tempi relativi alla richiesta corrente hanno senso per l'ottimizzazione, per cui il tempo nel core di symfony non viene visualizzato. Ecco perché tale valore non è la somma del tempo totale. 
     270  * Clicca sulla X rossa a destra per chiuderla. 
     271 
     272Figura 16-5 - La sezione del db mostra le query eseguite per la richiesta corrente 
     273 
     274![La sezione del db mostra le query eseguite per la richiesta corrente](http://www.symfony-project.org/images/book/1_1/F1605.png "La sezione del db mostra le query eseguite per la richiesta corrente") 
     275 
     276Figura 16-6 - L'icona dell'orologio mostra i tempi di esecuzione per categoria 
     277 
     278![L'icona dell'orologio mostra i tempi di esecuzione per categoria](http://www.symfony-project.org/images/book/1_1/F1606.png "L'icona dell'orologio mostra i tempi di esecuzione per categoria") 
     279 
     280>**SIDEBAR** 
     281>Aggiungere il tuo timer 
     282>Symfony usa la classe `sfTimer` per calcolare il tempo utilizzato nella configurazione, nel modello, azione e vista. Utilizzando lo stesso oggetto, puoi calcolare un processo custom e visualizzare il risultato con gli altri timer nella web debug toolbar. Questo può risultare molto utile quando lavori sull'ottimizzazione delle performance. 
     283> 
     284>Per inizializzare il timing su uno specifico frammento di codice, chiama il metodo `getTimer()`. Esso restituirà un oggetto sfTimer e comincerà il calcolo. Chiama il metodo `addTime()` su tale oggetto per fermare il calcolo. Il tempo necessario sarà disponibile tramite il metodo `getElapsedTime()`, e visualizzato nella toolbar insieme agli altri. 
     285> 
     286>     [php] 
     287>     // Initialize the timer and start timing 
     288>     $timer = sfTimerManager::getTimer('myTimer'); 
     289> 
     290>     // Do things 
     291>     ... 
     292> 
     293>     // Stop the timer and add the elapsed time 
     294>     $timer->addTime(); 
     295> 
     296>     // Get the result (and stop the timer if not already stopped) 
     297>     $elapsedTime = $timer->getElapsedTime(); 
     298> 
     299>Il beneficio derivante dal dare un nome od ogni timer è quello di poter accumulare i timing. Ad esempio, se il timer `myTimer` viene utilizzato in una utility chiamata due volte a richiesta, la seconda chiamata a `getTimer('myTimer')` farà ripartire il timing dall'ultimo punto in cui è stato chiamato il metodo `addTime()`, sommando. Chiamando `getCalls()` sull'oggetto timer troverai il numero di volte in cui un timer è stato lanciato, ed anche tale informazione viene visualizzata nella toolbar. 
     300> 
     301>     [php] 
     302>     // Get the number of calls to the timer 
     303>     $nbCalls = $timer->getCalls(); 
     304> 
     305>In modalità Xdebug, i messaggi di log sono molto più ricchi. Tutti gli script PHP e le funzioni chiamate vengono loggate, e symfony sa come collegare tale informazioni con i propri log interni. Ogni linea dei messaggi di log finisce con un pulsante con una doppia freccia, che puoi cliccare per vedere più informazioni sulla richiesta relativa. Se qualcosa andasse male, la modalità Xdebug ti fornisce la maggior quantità possibile di dettagli per capire dove e come. 
     306 
     307>**NOTE** 
     308>La web debug toolbar non è inclusa per default in risposte Ajax e documenti che non abbiano un content-type HTML. Per le altre pagine, puoi disabilitare la toolbar manualmente da dentro un'azione chiamando semplicemente `sfConfig::set('sf_web_debug', false)`. 
     309 
     310### Debugging manuale 
     311 
     312Avere accesso ai messaggi del framework di debug è carino, ma è meglio avere la capacità di loggare i tuoi propri messaggi. Symfony mette a disposizione dei collegamenti, disponibili sia nelle template che nelle azioni, per tenere traccia dei tuoi eventi durante l'esecuzione. 
     313 
     314I tuoi messaggi di log appaiono sia nei file di log di symfony sia nella toolbar, esattamente come gli eventi normali. (Il Listato 16-4 ne mostrava la sintassi) Un messaggio personalizzato è un buon modo di controllare il valore di una variabile in una template, ad esempio. Il Listato 16-11 mostra come usare la web debug toolbar per il feedback dello sviluppatore dalla template (da un'azione puoi usare `$this->logMessage()`). 
     315 
     316Listato 16-11 - Inserire un messaggio nel log per il debugging 
     317 
     318    [php] 
     319    <?php use_helper('Debug') ?> 
     320    ... 
     321    <?php if ($problem): ?> 
     322      <?php log_message('{sfAction} been there', 'err') ?> 
     323      ... 
     324    <?php endif ?> 
     325 
     326L'utilizzo del livello `err` garantisce che il messaggio sarà chiaramente visibile nella lista dei messaggi, come mostrato in Figura 16-7. 
     327 
     328Figura 16-7 - Un messaggio personalizzato appare nella sezione logs & msgs della web debug toolbar 
     329 
     330![Un messaggio personalizzato appare nella sezione logs & msgs della web debug toolbar](http://www.symfony-project.org/images/book/1_1/F1607.png "Un messaggio personalizzato appare nella sezione logs & msgs della web debug toolbar") 
     331 
     332Se tu non volessi aggiungere una linea al log, ma semplicemente tracciare un valore, dovresti usare `debug_message` invece di `log_message`. Tale metodo (esiste anche un helper con lo stesso nome) visualizza un messaggio nella toolbar, all'inizio della sezione logs & msgs. Controlla il Listato 16-12 per un esempio. 
     333 
     334Listato 16-12 - Inserire un messaggio nella web debug toolbar 
     335 
     336    [php] 
     337    // From an action 
     338    $this->debugMessage($message); 
     339 
     340    // From a template 
     341    <?php use_helper('Debug') ?> 
     342    <?php debug_message($message) ?> 
     343 
     344Usare symfony fuori da un contesto web 
     345-------------------------------------- 
     346 
     347Potresti voler eseguire uno script da linea di comando (o tramite cron) con accesso a tutte le classi e le feature di symfony, per esempio per lanciare dei job che inviino email o per aggiornare periodicamente il tuo modello tramite un calcolo intensivo per il processore. Il modo semplice di farlo è creare uno script PHP che riproduca i primi passi di un front controller, in modo che symfony sia inizializzato propriamente. Puoi anche usare il sistema a linea di comando di symfony, per sfruttare i vantaggi del parsing dei parametri e dell'inizializzazione automatica del database. 
     348 
     349L'inizializzazione di symfony richiede solo un paio di righe di codice PHP. Puoi sfruttare tutte le feature di symfony creando un file PHP, per esempio sotto la cartella `lib/` del tuo progetto, iniziando con le righe mostrate nel Listato 16-13. 
     350 
     351Listato 16-13 - Semplice script batch, in `lib/myScript.php` 
     352 
     353    <?php 
     354      
     355    require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php'); 
     356    $configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'dev', true); 
     357    sfContext::createInstance($configuration); 
     358      
     359    // Remove the following lines if you don't use the database layer 
     360    $databaseManager = new sfDatabaseManager($configuration); 
     361    $databaseManager->loadConfiguration(); 
     362      
     363    // add code here 
     364 
     365Assomiglia molto alle prime righe del front controller (vedi Chapter 6), perché queste righe fanno la stessa cosa: inizializzano symfony, fanno il parsing delle configurazioni di un progetto e di un'applicazione. Nota che il metodo `ProjectConfiguration::getApplicationConfiguration` si aspetta tre parametri: 
     366 
     367  * il nome di un'applicazione an application name 
     368  * il nome di un ambiente 
     369  * un booleano, che definisce se il debug deve essere abilitato o meno 
     370 
     371Per eseguire il tuo codice, basta richiamare lo script da linea di comando: 
     372 
     373    > php lib/myScript.php 
     374 
     375### Task personalizzati (nuovo in symfony 1.1) 
     376 
     377Un modo alternativo di creare script personalizzati da linea di comando usando symfony è scrivere un task di symfony. Proprio come i task `cache:clear` e `propel:build-model`, puoi lanciare questi tuoi task personalizzati da linea di comando con `php symfony`. I task personalizzati hanno la possibilità di fare il parsing dei parametri e delle opzioni della linea di comando, possono includere dei propri testi di aiuto, e possono estendere dei task esistenti. 
     378 
     379Un task personalizzato è solo una classe che estende `sfBaseTask` e va collocata sotto la cartella `lib/task/`, o sotto la radice del progetto o nella cartella di un plugin. Il nome deve terminare con 'Task.class.php'. Il Listato 16-14 mostra un esempio di task personalizzato. 
     380 
     381Listato 16-14 - Task di esempio, in `lib/task/testHelloTask.class.php` 
     382 
     383    [php] 
     384    class testHelloTask extends sfBaseTask 
     385    { 
     386      protected function configure() 
     387      { 
     388        $this->namespace = 'test'; 
     389        $this->name = 'hello'; 
     390        $this->briefDescription = 'Says hello'; 
     391      } 
     392      
     393      protected function execute() 
     394      { 
     395        // your code here 
     396        $this->log('Hello, world!'); 
     397      } 
     398    } 
     399 
     400Il codice scritto nel metodo `execute` ha accesso a tutte le librerie di symfony, proprio come il precedente script batch. La differenza è nel modo in cui richiami il task personalizzato:  
     401 
     402    > php symfony test:hello 
     403 
     404Il nome del task proviene dalle proprietà protette `namespace` e `name` (non dal nome della classe, né dal nome del file). E siccome il tuo task è integrato nella linea di comando di symfony, compare nella lista dei task se scrivi: 
     405 
     406    > php symfony 
     407 
     408Piuttosto che scriverti da solo uno scheletro per i task, puoi usare il task di symfony `generate:task`. Esso crea un task vuoto, ed ha molte opzioni di personalizzazione. Sii certo di controllarle richiamando: 
     409 
     410    > php symfony help generate:task 
     411 
     412I task possono accettare dei parametri (obbligatori, in un ordine predefinito) e delle opzioni (parametri opzionali e non ordinati). Il Listato 16-15 mostra un task più completo, che sfrutta tutte queste caratteristiche. 
     413 
     414Listato 16-15 - Task di esempio più complesso, in `lib/task/mySecondTask.class.php` 
     415 
     416    [php] 
     417    class mySecondTask extends sfBaseTask 
     418    { 
     419      protected function configure() 
     420      { 
     421        $this->namespace        = 'foo'; 
     422        $this->name             = 'mySecondTask'; 
     423        $this->briefDescription = 'Does some neat things, with style'; 
     424        $this->detailedDescription = <<<EOF 
     425    The [foo:mySecondTask|INFO] task manages the process of achieving things for you. 
     426    Call it with: 
     427      
     428      [php symfony foo:mySecondTask frontend|INFO] 
     429      
     430    You can enable verbose output by using the [verbose|COMMENT] option: 
     431      
     432      [php symfony foo:mySecondTask frontend --verbose=on|INFO] 
     433    EOF; 
     434        $this->addArgument('application', sfCommandArgument::REQUIRED, 'The application name'); 
     435        $this->addOption('verbose', null, sfCommandOption::PARAMETER_REQUIRED, 'Enables verbose output', false); 
     436      } 
     437      
     438      protected function execute($arguments = array(), $options = array()) 
     439      { 
     440        // add code here 
     441      
     442      } 
     443    } 
     444 
     445>**NOTE** 
     446>Se il tuo task ha bisogno di accedere al database, dovrebbe estendere `sfPropelBaseTask` invece che `sfBaseTask`. L'inizializzazione del task si occuperà allora di caricare le classi Propel addizionali. Puoi iniziare una connessione al database nel metodo `execute()` richiamando: 
     447> 
     448>    $databaseManager = new sfDatabaseManager($this->configuration); 
     449> 
     450> Se la configurazione del task definisce dei parametri `application` ed `env`, questi sono considerati automaticamente quando viene costruita la configurazione del task, in modo che il task possa usare ogni connessione definita nel tuo `databases.yml`. Di default, gli scheletri generati da `generate:task` includono tale inizializzazione. 
     451 
     452Per ulteriori esempi sulle abilità del sistema dei task, guarda i sorgenti dei task predefiniti di symfony. 
     453 
     454Se dichiari un task con lo stesso nome di uno già esistente, la tua classe sovrascrive il task esistente. Questo vuol dire che un plugin può sovrascrivere un task di symfony, e che un progetto può sovrascrivere il task di un plugin ed un task di symfony. Aggiungilo all'abilità di estendere una classe task esistente ed avrai un sistema a linea di comando molto estensibile! 
     455 
     456Popolare un database 
     457-------------------- 
     458 
     459Nel processo di sviluppo di un'applicazione, spesso gli sviluppatori devono affrontare la problematica della popolazione di un db. Esiste qualche soluzione specifica, ma nessuna che possa essere usata in generale sulla base di un E/R. Grazie all'oggetto `sfPropelData` ed a YAML, symfony può trasferire automaticamente dati da un file di testo ad un database. Anche se potrebbe sembrare che scrivere un file di testo necessiti di più tempo che utilizzare un'interfaccia CRUD, alla fine noterai che invece ne risparmi. 
     460 
     461 
     462### Sintassi di file fixture 
     463 
     464Symfony può leggere file di dati che seguano una sintassi YAML molto semplice, presupposto che tali file siano situati nella cartella `data/fixtures/`. I file fixture sono organizzati in classi, ogni sezione di una classe comincia con il nome della classe ed un header. Per ogni classe, i record chiamati con un nome unico sono identificati da coppie `fieldname: value`. Il Listato 16-16 mostra un esempio di file di dati per la popolazione. 
     465 
     466Listato 16-16 - Esempio di file fixture, in `data/fixtures/import_data.yml` 
     467 
     468    Article:                             ## Insert records in the blog_article table 
     469      first_post:                        ## First record label 
     470        title:       My first memories 
     471        content: | 
     472          For a long time I used to go to bed early. Sometimes, when I had put 
     473          out my candle, my eyes would close so quickly that I had not even time 
     474          to say "I'm going to sleep." 
     475 
     476      second_post:                       ## Second record label 
     477        title:       Things got worse 
     478        content: | 
     479          Sometimes he hoped that she would die, painlessly, in some accident, 
     480          she who was out of doors in the streets, crossing busy thoroughfares, 
     481          from morning to night. 
     482 
     483 
     484Symfony traduce le colonne chiavi in metodi setter utilizzando un convertitore camelCase (`setTitle(), setContent()`). Ciò significa ad esempio che tu potresti definire una chiave password anche se effettivamente nella tabella un campo password non esiste; dovresti solo definire un metodo `setPassword()` nell'oggetto `User`, potendo così popolare le altre colonne basandoti sulla password (ad esempio, una sua versione hash). 
     485 
     486Le chiavi primarie non hanno bisogno di essere definite. Dato che sono campi auto-increment, il database sa come comportarsi. 
     487 
     488Anche le colonne `created_at` non ne hanno bisogno, perché symfony sa che i campi che si chiamano in quel modo devono essere impostati con l'ora corrente. 
     489 
     490### Lanciare l'importazione 
     491 
     492Il task `propel:data-load` importa i dati dai file YAML al database. Le impostazioni di connessione vengono dal file `databases.yml`, perciò c'è bisogno di un nome di applicazione per farlo girare. Opzionalmente puoi specificare un ambiente aggiungendo l'opzione `--env` (`dev` è il default). 
     493 
     494    > php symfony propel:data-load frontend 
     495 
     496Questo comando legge tutti i file fixture nella cartella `data/fixtures/` ed inserisce i record nel db. Per default, esso sostituisce i dati esistenti, ma se l'ultimo argomento della chiamata è `append`, il comando aggiungerà i dati. 
     497 
     498    > php symfony propel:data-load frontend append 
     499 
     500Puoi anche specificare un altro file fixture o cartella nella chiamata. In questo caso, aggiungi un path relativo alla cartella `data/` del progetto. 
     501 
     502    > php symfony propel:data-load frontend --dir[]=data/myfixtures 
     503 
     504### Usare tabelle collegate 
     505 
     506Ora sai come importare dati in tabelle singole, ma come funziona con chiavi importate? Dato che le chiavi primarie non sono incluse nelle fixture, c'è bisogno di un modo alternativo. 
     507 
     508Torniamo all'esempio del Capitolo 8, dove la tabella `blog_article` è collegata alla `blog_comment`, come mostrato in Figura 16-8. 
     509 
     510Figura 16-8 - Esempio di modello database relazionale 
     511 
     512![Esempio di modello database relazionale](http://www.symfony-project.org/images/book/1_1/F1608.png "Esempio di modello database relazionale") 
     513 
     514Ecco dove le etichette date ai record risultano veramente utili. Per aggiungere un campo `Comment` all'articolo `first_post`, devi solo aggiungere le linee del Listato 16-17 al file `import_data.yml`. 
     515 
     516Listato 16-17 - Aggiungere record ad una tabella collegata, in `data/fixtures/import_data.yml` 
     517 
     518    Comment: 
     519      first_comment: 
     520        article_id:   first_post 
     521        author:       Anonymous 
     522        content:      Your prose is too verbose. Write shorter sentences. 
     523 
     524Il task `propel:data-load` riconoscerà la label che avevi precedentemente dato ad un articolo nel file `import_data.yml`, per cui rintraccerà la chiave primaria del corrispondente record nella tabella `Article` per impostare il campo `article_id`. Non vedrai nemmeno gli ID dei record; li collegherai tramite le label, ciò non potrebbe essere più semplice. 
     525 
     526L'unico vincolo per i record collegati è che gli oggetti chiamati nelle chiavi importate devono essere definiti prima nel file; che è poi quello che faresti se li definissi uno a uno. I file dati vengono parsati dall'alto al basso, per cui è importante l'ordine in cui sono scritti i record. 
     527 
     528<b>Nuovo in symfony 1.1</b>: Funziona anche per relazioni molti-a-molti, in cui due classi sono collegate tramite una terza classe. Per esempio, un `Article` può avere divers `Authors`, ed un `Author` può avere diversi `Articles`. Di solito usi una classe `ArticleAuthor` per gestirlo, corrispondene ad una tabella `article_author` con delle colonne `article_id` e `author_id`. Il Listato 16-18 mostra come scrivere un file fixture per definire delle relazioni molti-a-molti con questo modello. Nota che le tabelle usano nomi al plurale: è questo che attiva la ricerca di una classe di tramite. 
     529 
     530Listato 16-18 - Aggiungere un record ad un tabella legata da una relazione molti-a-molti, in `data/fixtures/import_data.yml` 
     531 
     532    Author: 
     533      first_author: 
     534        name: John Doe 
     535        article_authors: [first_post, second_post] 
     536 
     537Un file dati può contenere le dichiarazioni di diverse classi. Ma se hai bisogno di inserire molti dati per diverse tabelle, il tuo file fixture potrebbe diventare troppo lungo e non facile da manipolare. 
     538 
     539Il task `propel:data-load` fa il parsing di tutti i file della cartella `fixtures/`, per cui potresti suddividere i file YAML in parti più piccole. L'unica cosa da tenere a mente è l'ordine per le chiavi importate, per cui per essere sicuro di preservarlo puoi ad esempio aggiungere un prefisso numerico ai file. 
     540 
     541    100_article_import_data.yml 
     542    200_comment_import_data.yml 
     543    300_rating_import_data.yml 
     544 
     545Distribuire applicazioni 
     546------------------------ 
     547 
     548Symfony offre comandi veloci per sincronizzare due versioni di un sito web. Tali comandi vengono principalmente usati per fare il deploy di un sito da un server di sviluppo ad uno di produzione, connesso ad Internet. 
     549 
     550 
     551### Congelamento di un progetto per il trasferimento tramite FTP 
     552 
     553Il modo più comune per il deploy di un sito in produzione è quello di trasferire tutti i suoi file tramite FTP (o SFTP). Ad ogni modo, i progetti symfony usano le proprie librerie, ed a meno di sviluppare in una sandbox (che non è consigliato), o se le cartelle `lib/` e `data/` sono collegate tramite `svn:externals`, tali directory non si trovano nella cartella del progetto. Sia utilizzando la PEAR che link simbolici, riprodurre la stessa struttura di cartelle può richiedere tempo. 
     554 
     555Ecco perché symfony fornisce una utility per "congelare" un progetto, ovvero per copiare le necessarie librerie nelle cartelle del progetto `data/`, `lib/` e `web/`. In tal modo il progetto diventa come una sandbox, un'applicazione stand-alone. 
     556 
     557    > php symfony project:freeze symfony_data_dir 
     558 
     559Il parametro `symfony_data_dir` è il percorso della cartella dei dati di symfony (se hai installato symfony tramite Subversion o un archivio, questa cartella è nella stessa cartella di `lib` di symfony; se hai installato symfony tramite il pacchetto PEAR, questa cartella si trova nella cartella `data` di PEAR). 
     560 
     561Una volta che il progetto è congelato, puoi trasferire la cartella del progetto in produzione, e tutto funzionerà senza bisogno di PEAR, link simbolici o quant'altro. 
     562 
     563>**TIP** 
     564>Diversi progetti congelati possono funzionare sullo stesso server con diverse versioni di symfony senza alcun problema. 
     565 
     566Per riportare un progetto al suo stato iniziale, usa il task `project:unfreeze`. Esso elimina le cartelle `data/symfony/`, `lib/symfony/` e `web/sf/`. 
     567 
     568    > php symfony project:unfreeze 
     569 
     570Nota che se tu avessi avuto link simbolici in un'installazione symfony prima del congelamento, symfony se lo ricorderebbe e li ripristinerebbe nella loro posizione originale. 
     571 
     572### Usare rsync per il trasferimento incrementale 
     573 
     574Inviare la cartella di root di un progetto via FTP per il primo trasferimento va bene, ma quando hai bisogno di aggiornare la tua applicazione con un update dove solo alcuni file sono cambiati, tale metodo non è ideale. Dovresti caricare di nuovo tutto il progetto, con spreco di tempo e banda, oppure cercare nel progetto solo i file modificati e trasferirli. Ciò è un lavoro noioso e incline ad errori. Inoltre, il sito in produzione potrebbe risultare, durante il trasferimento, non disponibile o con bug. 
     575 
     576La soluzione supportata da symfony è una sincronizzazione via rsync tramite un layer SSH. Rsync ([http://samba.anu.edu.au/rsync/](http://samba.anu.edu.au/rsync/)) è una utility a linea di comando che fornisce un trasferimento incrementale veloce, ed è open source. Tramite il trasferimento incrementale, solo i file modificati verranno inviati; quelli che non sono cambiati non saranno spediti al server in produzione. Se un file è stato cambiato parzialmente, solo tale parte verrà inviata. Il vantaggio principale di questa tecnica è quindi che solo piccole porzioni di dati verranno spediti, ed il procedimento risulterà molto veloce. 
     577 
     578Symfony aggiunge SSH alla sincronizzazione rsync per la sicurezza del trasferimento. Sempre più hosting commerciali mettono a disposizione un tunnel SSH per avere upload sicuri sui propri server, e questo è una buona pratica per evitare falle di sicurezza. 
     579 
     580Il client SSH chiamato da symfony utilizza le impostazioni di connessione specificate nel file `config/properties.ini`. Il Listato 16-19 mostra un esempio di impostazioni di connessione per un server di produzione. Scrivi le impostazioni del tuo server di produzione in tale file prima di qualsiasi sincronizzazione. 
     581 
     582Listato 16-19 - Esempio di impostazioni di connessione per una sincronizzazione con un server, in `myproject/config/properties.ini` 
     583 
     584    [symfony] 
     585      name=myproject 
     586 
     587    [production] 
     588      host=myapp.example.com 
     589      port=22 
     590      user=myuser 
     591      dir=/home/myaccount/myproject/ 
     592 
     593>**NOTE** 
     594>Non confondere il server di produzione (il server host, come definito nel file `properties.ini` del progetto) con l'ambiente di produzione (il front controller e la configurazione usata in produzione, come riportato nei file di configurazione di un'applicazione). 
     595 
     596Eseguire un rsync su SSH richiede diversi comandi, e la sincronizzazione può ricorrere molte volte nella vita di un'applicazione. Fortunatamente, symfony automatizza tale processo con un semplice comando: 
     597 
     598    > php symfony project:deploy production 
     599 
     600Questo comando esegue rsync in dry mode; ciò significa che mostra quali file dovrebbero essere sincronizzati senza farlo veramente. Se vuoi effettivamente eseguire la sincronizzazione, devi esplicitarlo aggiungendo `go`. 
     601 
     602    > php symfony project:deploy production --go 
     603 
     604Non dimenticare di pulire la cache del server di produzione dopo una sincronizzazione. 
     605 
     606>**TIP** 
     607>Alcune volte compaiono dei bug in produzione che non sono invece presenti in sviluppo. Nel 90% dei casi, ciò è dovuto a differenze nelle versioni (di PHP, web server o database) o nelle configurazioni. Per evitare spiacevoli sorprese, dovresti definire la configurazione di PHP del file `php.yml` della tua applicazione, in modo che venga controllato che l'ambiente di sviluppo applichi le stesse impostazioni. Consulta il Capitolo 19 per maggiori informazioni in merito. 
     608 
     609>**SIDEBAR** 
     610>La tua applicazione è completata? 
     611>Prima di spedire la tua applicazione in produzione, dovresti accertarti che sia pronta per l'utilizzo pubblico. Controlla che le seguenti cose siano effettivamente state fatte prima di fare il deploy: 
     612> 
     613>Le pagine di errore dovrebbero essere personalizzate con il look and feel della tua applicazione. Consulta il Capitolo 19 per capire come personalizzare gli errori 500, 404 e le pagine di sicurezza, e la sezione "Gestire un'applicazione in produzione" più avanti in questo capitolo per vedere come personalizzare le pagine mostrate quando il tuo sito non è disponibile. 
     614> 
     615>Il modulo `default` dovrebbe essere rimosso dall'array `enabled_modules` in `settings.yml`, in modo che non appaiano pagine symfony per errore. 
     616> 
     617>Il meccanismo di gestione delle sessioni usa un cookie lato client, e tale cookie si chiama `symfony` per default. Prima di fare il deploy, dovresti probabilmente rinominarlo per evitare di mostrare che la tua applicazione si basa su symfony. Controlla il Capitolo 6 per vedere come personalizzare il nome del cookie nel file `factories.yml`. 
     618> 
     619>Il file `robots.txt`, situato nella cartella `web/` del progetto, è vuoto per default. Dovresti personalizzarlo per informare gli spider web ed altri robot di quale parte del sito dovrebbero navigare e quale dovrebbero evitare. La maggior parte delle volte, tale file viene usato per evitare di indicizzare certi URL space, ad esempio pagine che richiedono molte risorse, pagine che non ne abbiano bisogno (come archivi di bug), o URL space infiniti dove i robot potrebbero rimanere intrappolati. 
     620> 
     621>I browser moderni richiedono un file `favicon.ico` quando un utente naviga per la prima volta il tuo sito, per rappresentare la tua applicazione con un'icona nella barra degli indirizzi e nei bookmark. Fornire tale file non solo completerà il look and feel della tua applicazione, ma eviterà anche la presenza di errori 404 nei file di log del server. 
     622 
     623### Ignorare file irrilevanti 
     624 
     625Se sincronizzi il tuo progetto symfony con un host di produzione, alcuni file e cartelle dovrebbero non essere inviate: 
     626 
     627  * Tutte le cartelle di versioning (`.svn/`, `CVS/` e così via) ed il loro contenuto sono necessari solo per lo sviluppo e l'integrazione. 
     628  * Il front controller e l'ambiente di sviluppo non devono essere disponibili all'utente finale. Gli strumenti di debugging e di logging disponibili durante l'utilizzo dell'applicazione tramite tale controller rallentano ne rallentano l'esecuzione e forniscono informazioni sulle variabili di core delle tue azioni. E' qualcosa da tenere lontano dal pubblico. 
     629  * Le cartelle `cache/` e `log/` di un progetto non devono venire cancellate sul server di produzione ad ogni sincronizzazione. Anche queste cartelle devono essere ignorate. Se hai una cartella `stats/`, probabilmente dovrebbe essere trattata nello stesso modo. 
     630  * I file caricati dagli utenti non devono essere trasferiti. Una delle buone pratiche dei progetti symfony è quella di tenere i file caricati nella cartella `web/uploads/`. Questo ti permette di escludere tali file dalla sincronizzazione puntando ad una sola cartella. 
     631 
     632Per escludere file dalla sincronizzazione rsync, apri e modifica il file `rsync_exclude.txt` nella cartella `myproject/config/`. Ogni linea può contenere un nome di file, di directory od un pattern. La struttura di file di symfony è organizzata logicamente, e disegnata per minimizzare il numero di file e cartelle da escludere manualmente da una sincronizzazione. Vedi il Listato 16-20 per un esempio. 
     633 
     634Listato 16-20 - Esempio di impostazione di esclusione rsync, in `myproject/config/rsync_exclude.txt` 
     635 
     636    .svn 
     637    /cache/* 
     638    /log/* 
     639    /stats/* 
     640    /web/uploads/* 
     641    /web/frontend_dev.php 
     642 
     643>**NOTE** 
     644>Le cartelle `cache/` e `log/` non devono essere sincronizzate con il server di sviluppo, ma devono almeno esistere sul server di produzione. Creale a mano se non sono già presenti nella cartella `myproject/`. 
     645 
     646### Gestire un'applicazione in produzione 
     647 
     648Il comando usato più spesso in server di produzione è `clear-cache`. Lo devi eseguire ogni qualvolta aggiorni symfony od il tuo progetto (ad esempio tramite il comando `sync`), ed ogni volta che cambi la configurazione di produzione. 
     649 
     650    > symfony cache:clear 
     651 
     652>**TIP** 
     653>Se l'interfaccia a linea di comando non fosse disponibile sul tuo server di produzione, puoi ancora pulire la cache manualmente cancellando il contenuto della cartella `cache/`. 
     654 
     655Puoi disabilitare temporaneamente la tua applicazione, ad esempio quando devi aggiornare una libreria od una grande quantità di dati. 
     656 
     657    > php symfony project:disable APPLICATION_NAME ENVIRONMENT_NAME 
     658 
     659Per default, un'applicazione disabilitata mostra la pagina `$sf_symfony_lib_dir/exception/data/unavailable.php`, ma puoi creare la tua pagina personalizzata `unavailable.php` nella cartella `config/` del progetto, symfony userà quella. 
     660 
     661Il task `project:enable` riabilita l'applicazione e pulisce la cache. 
     662 
     663    > symfony project:enable APPLICATION_NAME ENVIRONMENT_NAME 
     664 
     665 
     666>**SIDEBAR** 
     667>Visualizzare una pagina non disponibile mentre si pulisce la cache 
     668>Se imposti il parametro `check_lock` a `on` nel file `settings.yml`, symfony bloccherà l'applicazione durante la pulizia della cache, e tutte le richieste che arriveranno prima che la pulizia sia stata completata, verranno ridirezionate su una pagina che dice che l'applicazione è temporaneamente non disponibile. Se la cache è molto ampia, il ritardo necessario potrebbe essere maggiore di qualche millisecondo, e se il traffico sul tuo sito è alto questa è un'impostazione consigliata. Questa pagina che mostra il messaggio di non disponibile è la stessa di quella visualizzata quando chiami il task `disable`. Il parametro `check_lock` è disattivato per default perché ha un impatto leggermente negativo sulle prestazioni. 
     669> 
     670>Il task `project:clear-controllers` pulisce la cartella `web/` da tutti i controller che non siano quelli che girano in produzione. Se non includi il controller di sviluppo nel file `rsync_exclude.txt`, questo comando evita che una backdoor riveli gli interni della tua applicazione. 
     671> 
     672>     > symfony project:clear-controllers 
     673> 
     674>I permessi dei file e cartelle di progetto possono essere sbagliati se usi un checkout da un repository SVN. Il task `project:permissions` rimette a posto i permessi, ad esempio per cambiare i permessi di `cache/` e `log/` in 0777 (tali cartelle hanno bisogno di essere scrivibili dal framework per funzionare correttamente). 
     675> 
     676>     > symfony project:permissions 
     677 
     678Sommario 
     679-------- 
     680 
     681Combinando i log di PHP e di symfony, puoi facilmente monitorare e debuggare le tue applicazioni. Durante lo sviluppo, la modalità di debug, le eccezioni, e la web debug toolbar ti aiutano a trovare i problemi. Puoi anche inserire messaggi personalizzati nei file di log o nella toolbar per facilitare il debug. 
     682 
     683L'interfaccia a linea di comando fornisce un grande numero di strumenti che facilitano la gestione delle tue applicazioni, durante le fasi di sviluppo e di produzione. Soprattutto, il popolamento dei dati, il congelamento e la sincronizzazione fanno risparmiare molto tempo. 
     684 
     685}}}