25 Nov 2011 3 commenti
Nel precedente articolo avevamo visto come creare un semplice guestbook con CodeIgniter e l'ultimo tassello mancante per completare il quadro era l'inserimento dei commenti tramite un form.
Per integrare tutto ciò dovremo:
- creare un form all'interno della view tale da consentire all'utente l'inserimento del commento;
- creare all'interno del controller guestbook un apposito metodo, newcomment(), che si occuperà dell'insermento del commento: questo metodo dovrà validare i dati e se risulteranno esatti inserire il commento nella tabella MySql per mezzo del model (guestbook_model);
Ma adiamo con ordine.
Costruzione del form
La costruzione dei form potrà essere eseguita attraverso semplice markup all'interno della view. Nel caso di un form per i commenti avremo nel nostro esempio:
<form action="http://localhost/index.php/guestbook/newcomment" accept-charset="utf-8" method="post"> <p> <label for="nome">Nome</label><br /> <input type="text" name="nome" value="" /> </p> <p> <label for="email">Email</label><br /> <input type="text" name="email" value="" /> </p> <p> <label for="website">Website</label><br /> <input type="text" name="website" value="" /> </p> <p> <label for="commento">Testo</label><br /> <textarea name="commento" cols="30" rows="10" ></textarea> </p> <p> <input type="submit" name="newcomment" value="Invia" /> </p> </form>
Vorrei far notare un aspetto: l'action del form punta ad http://localhost/index.php/guestbook/newcomment. Questo ci costringerebbe nel momento in cui hostiamo on line il nostro applicativo a modificare gli URL. Sarebbe, quindi, utile rendere dinamico questo URL. Adesso vedremo come.
Infatti, in alternativa a questo modo di operare è utile ricorrere ad appositi helpers.
CodeIgniter dispone di helpers dedicati alla gestione degli URL e alla costruzione dei form: URL Helper ed Form Helper.
Ma spieghiamo anzitutto cosa sono questi helpers.
Cosa sono gli helpers
Un helper è una libreria di funzioni (non una classe) che a seguito del load potrà essere impiegata nelle view, nei controller o (più di rado) nei model.
Nei diversi helpers le funzioni sono raggruppate in modo omogeneo.
CodeIgniter dispone di una gamma di helpers: uno per gestire gli url, uno per costruire i form, uno per le date, uno per le stringhe, etc. etc.
Qualora nostre specifiche necessità lo richiedano potremo anche creare dei nostri helpers e collocarli nella cartella /application/helpers/.
Per poter utilizzare una o più funzioni incluse in un helper dovremo eseguire il load dell'helper di cui abbiamo bisogno. In assenza del load utilizzando una funzione ricompresa in un helper il nostro applicativo ci darà l'errore (fatal error) "Call to undefined function..." (chiamata di una funzione inesistente).
Il load di un helpers in CodeIgniter avviene attraverso il seguente comando:
$this->load->helper('NOME_HELPER');
Il load viene solitamente eseguito all'interno del controller (non all'interno della view).
Tuttavia, qualora vi siano degli helper che hanno un uso frequente valgono le analoghe considerazioni fatte nel precedente articolo sull'autoload.
Costruire il form attraverso l'uso dell'helper
Ai fini della realizzazione del nostro guestbook andremo ad impostare nell'autoload (application/config/autoload.php) i seguenti helpers:
$autoload['helper'] = array('url', 'form');
Si tratta di due helpers che tradizionalmente hanno un uso frequentissimo.
Il primo helper, URL helper, ci servirà per gestire gli url interni al nostro applicativo. Fra le principali funzioni presenti in questo helper troveremo:
- site_url(): ci darà come return un URL interno al nostro sito sulla base dei parametri impostati nel /application/config/config.php base_url, index_page, url_suffix;
- base_url(): analoga alla precedente ma non tiene conto dei parametri index_page, url_suffix (tiene conto solo di base_url);
- redirect(): esegue il redirect alla pagina indicata come parametro (senza la necessità di indicare la base_url, l'index_page o url_suffix).
Con l'ausilio di questi metodi potremo rendere dinamici gli URL: infatti modificando i parametri di configurazione (base_url, index_page, url_suffix) gli URL a cui si riferiscono tali funzioni si modificheranno automaticamente.
Il secondo helper, Form helper, è quello che impiegheremo nella costruzione dei form. Volendo fare una rapidissima carrelata delle principali funzioni disponibili:
- form_open(): ci darà come return il tag di apertura del form indicando come primo parametro l'action del form;
- form_input(): ci darà come return il tag input type text impostando il name con il primo parametro e il value con il secondo.
- form_submit(): ci datà come return il tag input type submit impostando il name con il primo parametro e il value con il secondo.
- form_close(): ci darà come return il tag di chiusura del form.
Ovviamente per i dettagli e i parametri delle diverse funzioni ricomprese nei due helpers in esame rimando all'User guide in cui troverete tutti i dettagli.
Per ottenere un analogo output rispetto a quello visto in precedenza impiegando il Form Helper all'interno della view avremo pertanto:
<?php echo form_open('/guestbook/newcomment', array('method'=>'post')); ?> <p> <?php echo form_label('Nome', 'nome'); ?><br /> <?php echo form_input(array('name'=>'nome') ); ?> </p> <p> <?php echo form_label('Email', 'email'); ?><br /> <?php echo form_input(array('name'=>'email') ); ?> </p> <p> <?php echo form_label('Website', 'website'); ?><br /> <?php echo form_input(array('name'=>'website') ); ?> </p> <p> <?php echo form_label('Testo', 'commento'); ?><br /> <?php echo form_textarea(array('name'=>'commento', 'rows' => 10, 'cols' => 30) ); ?> </p> <p> <?php echo form_submit(array('name'=>'newcomment', 'value'=>'Invia')); ?> </p> <?php echo form_close(); ?>
Potete ben comprendere come il suo utilizzo sia molto intuitivo e semplice da comprendere.
Da notare che nel primo parametro di form_open, con il quale indichiamo l'action, non indichiamo la base_url e la index_page del nostro applicativo dato che sarà CodeIgniter ad impostarlo dinamicamente sulla base dei parametri indicati nel file di configurazione /application/config/config.php.
La ricezione dei dati POST
Il form costruito punterà al controller guestbook e al metodo newcomment(). All'interno di questo metodo prima di procedere all'inserimento dei dati attraverso il guestbook_model (illustrato nel precedente articolo) dovremo anzitutto ricevere i dati, validarli e "filtrarli".
La ricezione dei dati con CodeIgniter avviene con la Input Class. Per utilizzarla non occorre eseguire il load dato che viene inizializzata automaticamente.
Per ottenere il valore di un dato inviato con metodo post avremo:
$value = $this->input->post('nome_input');
In caso di input inesistente questo metodo ci datà come return FALSE.
L'utilità di tali metodi risiede nel fatto che in essi sono integrate le cosiddette "security filtering function" che renderanno il nostro codice molto più sicuro:
- distrugge le variabili GET dato che CodeIgniter (di default) non le impiega;
- verranno annullati gli "effetti" in caso di register_global settato su on;
- filtra le chiavi degli array POST e COOKIE consentendo solo caratteri alfanumerici e qualche altro;
- fornisce protezioni da attacchi XXS (Cross-site scripting Hacks);
- standardizza i caratteri di new line in \n.
Pertanto nei nostri codici, salvo caso di debug, non avremo mai la variabile $_POST ma per recuperare i dati utilizzeremo sempre la Input Class.
La validazione dei dati
Per ciò che concerne la validazione dei dati, il loro "filtraggio" e la gestione dei messaggi di errore da mostrare all'utente si utilizzerà, invece, la Form Validation Class. Personalmente trovo questa classe uno dei punti di maggior forza di CodeIgniter data la semplicità di utilizzo e l'alto grado di personalizzazione (spero di poterne parlarne nel dettaglio in un articolo specificamente dedicato).
La classe Validation Forms va applicata in questo ordine logico.
Anzitutto dovremo fissare per ogni input che lo richiedano le regole di validazione e filtraggio attraverso il metodo set_rules().
Questo accetta tre parametri:
- il nome dell'input all'interno del form (il name del tag <input>):
- il nome da visualizzare nei messaggi di errore;
- le regole di validazione e filtraggio da applicare all'input; in particolare la classe possiede metodi integrati (required, valid_email, min_length[numero di caratteri], etc. etc.), metodi "esterni" tramite callback (che non applicheremo in questo tutorial), o regole di "filtraggio" delle stringhe (trim, htmlspecialchar, md5, sha1, etc. etc.); Queste regole saranno indicate separandole le une dalle altre con il carattere |.
Per verificare che le regole di validazione risultino rispettate utilizzeremo il metodo run() che ci darà come return TRUE in caso validazione superata.
In caso di fallimento della validazione possiamo ottenere i messaggi di errore tramite la funzione validation_errors(). Essi saranno in lingua inglese (ma si potrà modificarli tramite apposita configurazione).
Cerchaimo di comprendere come integrare tutto ciò.
Validazione dei dati del nostro guestbook
Vediamo come si articolerà il metodo newcomment() del controller guestbook nel quale, dopo aver eseguito il load della classe Form Validation, andremo a settare le regole di validazione e filtraggio per ogni input per poi verificarle.
public function newcomment(){ /* eseguiamo il load della Form Validation Class */ $this->load->library('form_validation'); /* per ogni input indichiamo le regole (rules) di validazione con il metodo set_rules() */ /* validazione del campo 'nome': 1) applichiamo al valore la funzione trim() per eliminare gli spazi iniziali e finali 2) required per verificare che non sia una stringa vuota 3) applichiamo al valore la funzione htmlspecialchars() per immunizzare i caratteri pericolosi in caso di stampa a video */ $this->form_validation->set_rules('nome', 'nome', 'trim|required|htmlspecialchars'); /* validazione del campo 'email': 1) required per verificare che non sia una stringa vuota 2) valid_email per verificare la sintassi dell'indirizzo email */ $this->form_validation->set_rules('email', 'email', 'required|valid_email'); /* validazione del campo website 1) filtriamolo con htmlentities */ $this->form_validation->set_rules('website', 'website', 'htmlspecialchars'); /* validazione del campo 'commento': 1) applichiamo al valore la funzione trim() per eliminare gli spazi iniziali e finali 2) required per verificare che non sia una stringa vuota 3) min_lenght[6] per verificare che il commento abbia una lunghezza minima di 6 caratteri 4) applichiamo al valore la funzione htmlspecialchars() per immunizzare i caratteri pericolosi in caso di stampa a video */ $this->form_validation->set_rules('commento', 'commento', 'trim|required|min_length[6]|htmlspecialchars'); /* se la validazione è andata a buon fine*/ if($this->form_validation->run()==TRUE){ /* eseguamo il load del guestbook_model */ $this->load->model('guestbook_model'); /* applichaimo il metodo AddComment dell'user_model */ $this->guestbook_model->AddComment( $this->input->post('nome'), $this->input->post('email'), (string) $this->input->post('website'), $this->input->post('commento') ); /* redirect al guestbook */ redirect('/guestbook'); } /* altrimenti mostriamo i messsaggi di errore della validazione */ else{ echo validation_errors(); } }
I commenti presenti e il codice stesso è autoesplicativo.
Il codice definitivo
Andando quidi a ricapitolare il tutto, riprendendo il codice elaborato nel precedente articolo.
Il model del nostro applicativo sarà /application/guestbook_model.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); Class Guestbook_model extends CI_Model{ // CREATE public function AddComment($name, $email, $website, $comment){ $data = array( 'name' => $name, 'email' => $email, 'website' => $website, 'comment' => $comment, 'time_insert' => date('Y-m-d H:i:s') ); $this->db->insert('guestbook', $data); return $this->db->insert_id(); } // READ public function GetComment($id=null){ if(!is_null($id)){ $this->db->where('id', $id); } $this->db->order_by('time_insert', 'desc'); $query = $this->db->get('guestbook'); return $query->result(); } // UPDATE function update($id, $data){ $this->db->where('id', $id); $this->db->update('guestbook', $data); } // DELETE public function DeleteCommetById($id){ $this->db->where('id', $id); $this->db->delete('guestbook'); return $this->db->affected_rows(); } }
Il cotroller che si occuperà di gestire le richieste dell'utente sarà /application/controllers/guestbook.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); Class Guestbook extends CI_Controller { /* mostriamo i commenti presenti */ public function index(){ // load model gusetbook $this->load->model('guestbook_model'); // get data $data['titolo'] = 'Il mio guestbook con CodeIgniter'; $data['commenti'] = $this->guestbook_model->GetComment(); $data['numero_commenti'] = count($data['commenti']); // show view $this->load->view('guestbook_view', $data); } /* inseriamo un nuovo commento */ public function newcomment(){ $this->load->library('form_validation'); $this->form_validation->set_rules('nome', 'nome', 'trim|required|htmlspecialchars'); $this->form_validation->set_rules('email', 'email', 'required|valid_email'); $this->form_validation->set_rules('website', 'website', 'htmlspecialchars'); $this->form_validation->set_rules('commento', 'commento', 'trim|required|min_length[6]|htmlspecialchars'); if($this->form_validation->run()==TRUE){ // insert comment $this->load->model('guestbook_model'); $this->guestbook_model->AddComment( $this->input->post('nome'), $this->input->post('email'), (string) $this->input->post('website'), $this->input->post('commento') ); // redirect redirect('/guestbook'); } else{ // error validation echo validation_errors(); } } }
Infine, la view sarà /application/views/guestbook_view.php
<html> <head> <title><?php echo $titolo; ?></title> </head> <body> <h1><?php echo $titolo; ?></h1> <hr /> <?php foreach($commenti as $single) : ?> <div class="comment"> <p> Nome: <?php echo $single->name; ?> <br /> Email: <?php echo $single->email; ?> <br /> Website: <?php echo $single->website; ?> <br /> Data : <?php echo date('d m Y h:m', strtotime($single->time_insert)); ?> <br /> </p> <p> <?php echo $single->comment; ?> </p> </div> <hr /> <?php endforeach; ?> <?php echo form_open('/guestbook/newcomment', array('method'=>'post')); ?> <p> <?php echo form_label('Nome', 'nome'); ?><br /> <?php echo form_input(array('name'=>'nome') ); ?> </p> <p> <?php echo form_label('Email', 'email'); ?><br /> <?php echo form_input(array('name'=>'email') ); ?> </p> <p> <?php echo form_label('Website', 'website'); ?><br /> <?php echo form_input(array('name'=>'website') ); ?> </p> <p> <?php echo form_label('Testo', 'commento'); ?><br /> <?php echo form_textarea(array('name'=>'commento', 'rows' => 10, 'cols' => 30) ); ?> </p> <p> <?php echo form_submit(array('name'=>'newcomment', 'value'=>'Invia')); ?> </p> <?php echo form_close(); ?> </body> </html>
Conclusioni
Questa voleva essere una rapida esposizione di come si struttura un applicativo con CodeIgniter illustrandone i principali strumenti.
Ovviamente, si è sorvolato e sintetizzato molti aspetti che avrebbero richiesto una maggiore attenzione: per questi motivi i rimandi alla User Guide sono dovuti e necessari per comprendere a fondo come utilizzare ciascun metodo.
Per qualsiasi delucidazione o approfondimento non esistate a lasciarmi un commento e sarò ben lieto di rispondervi.
Olimpio Romanella
Sono un appassionato di Web Developing con un particolare debole per php. Mi dedico principalmente dello sviluppo back-end ed in particolare programmazione lato server con php, sviluppo di database relazionali MySql e progettazione di CMS di piccole e medie dimensioni.
Mi avvalgo del framework javascript Jquery, utilizzando molti dei suoi plugin e nei dei miei progetti utilizzo spesso il framework MVC Codeigniter.
mario
09 April 2014 ore 15:59
complimenti per le tue guide sono chiare, precise, essenziali.. SPETTACOLARE lavoro!