sabato 20 ottobre 2012

Guida Codeigniter 4 - Gestione del multilingua

Gestione del multilingua

L’internazionalizzazione di un sito di questi tempi è un mattone fondamentale per la diffusione dello stesso. Per questo motivo, CodeIgniter ne offre nativamente il supporto. Di base, le traduzioni della nostra applicazione devono risiedere in una determinata cartella, nominata a seconda della lingua, ad esempio:
application/language/english
application/language/italian
I file di traduzione devono terminare con il suffisso _lang.php e devono essere così strutturati:
/**
 * File application/language/italian/prova_lang.php
 */
$lang['chiave_1'] = "Messaggio tradotto 1";
$lang['chiave_2'] = "Messaggio tradotto 2";
//esempio pratico
$lang['welcome_title'] = "Benvenuti!";
Per poter essere disponibile a controller o viste, il file di traduzione deve essere caricato:
$this->lang->load('filename', 'language');
//seguendo l'esempio precedente
$this->lang->load('prova', 'italian');
Il primo parametro della funzione è il nome del file da caricare, senza estensione e senza suffisso; il secondo è la lingua desiderata (se omesso, CI utilizzerà la lingua predefinita, impostata in application/config/config.php), che coincide con il nome della sottocartella, ad esempio italian. Ora carichiamo una delle stringhe tradotte definite in precedenza:
echo $this->lang->line('welcome_title');
Per una internazionalizzazione completa, è necessario tradurre nelle lingue desiderate, con relative cartelle, anche i messaggi inglesi dei vari componenti di CodeIgniter, che si trovano in
system/language/english 

Prima parte della guida: Guida Codeigniter 1 - Introduzione
Seconda parte della guida: Guida Codeigniter 2 - Primi passi
Terza parte della guida: Guida Codeigniter 3 - Uso avanzato

EDIT:
Ho pubblicato la guida in formato PDF contenente tutti gli argomenti affrontati sul blog, liberamente scaricabile e stampabile. La trovate al link:
http://stefanobianchini.blogspot.it/2012/11/guida-codeigniter-modo-mio-pdf-in.html

Guida Codeigniter 3 - Uso avanzato

Uso avanzato

4.1  Rimuovere index.php dagli Url

Nell’installazione standard, la stringa "‘index.php"’ compare negli url di Codeingniter, ad esempio:
example.com/index.php/news/article/my_article
È possibile rimuovere quell’antiestetico index.php usando, ad esempio un file .htaccess se si sta lavorando su web server Apache, usando il modulo chiamato mod_rewrite e una logica chiamata "‘negativa"’: a parte determinate eccezioni (cartella assets, file robots.txt, il file index.php stesso) considera tutto ciò che viene richiesto come concatenato ad index.php.
RewriteEngine on
RewriteCond $1 !^(index\.php|assets|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
Non dimentichiamoci inoltre di modificare il file di configurazione impostando una determinata variabile vuota
$config['index_page'] = '';
Questa soluzione può non sempre funzionare. A seconda delle configurazioni dell’hosting / web server, può non dare il risultato sperato. In questi casi viene consigliato di tentare tutte le possibili configurazioni per la variabile che determina la stringa URI
/*
| Se AUTO (auto-detect) non funziona, prova uno dei seguenti
|
| 'PATH_INFO'           Uses the PATH_INFO
| 'QUERY_STRING'        Uses the QUERY_STRING
| 'REQUEST_URI'         Uses the REQUEST_URI
| 'ORIG_PATH_INFO'      Uses the ORIG_PATH_INFO
*/
$config['uri_protocol'] = 'AUTO';
Ad esempio, per il diffuso hosting aruba, è necessario il seguente .htaccess
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/system.*
RewriteCond $1 !^(index\.php|assets|robots\.txt)
RewriteRule ^(.*)$ index.php?/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php?/$1 [L]
 

Sessioni

Codeigniter offre un comodo strumento per mantenere informazioni relative ad un determinato utente, la classe Session. Bisogna subito chiarire che non fa uso delle classiche sessioni Php, ma anzi ha un meccanismo diverso, basato sui cookies oppure, fortemente consigliato, su un database. La visione classica di una sessione, in questo framework, è un cookies che contiene informazioni. Queste informazioni sono strutturate in modo da poter leggere e scrivere variabili di sessione in modo agile e semplice. Per rendere univoca la sessione e fare in modo che i dati siano relativi ad un solo utente, una sessione in CI è così strutturata:
  • dati di sessione (variabili)
  • id di sessione (univoco)
  • indirizzo ip dell’utente
  • user agent del browser dell’utente
  • timestamp dell’ultima attività
Di base queste informazioni vengono salvate su un cookie, il quale è notoriamente quanto di più insicuro ci sia in ambito web. C'è ovviamente la possibilità di cifrare il contenuto del cookie di sessione, impostando una determinata variabile all'interno del file di configurazione principale (/application/config/config.php)
$config['sess_encrypt_cookie']=TRUE;
Una limitazione da non poco conto è relativa alla dimensione dei dati salvabili in una sessione basata su cookies, ossia 4 KB. In caso di cifratura del cookie, questo limite si abbassa poiché gli algoritmi spesso aumentano la dimensione della stringa. Poiché le sessioni vengono usate soprattutto in caso di login da parte di un utente, ossia per contenere le informazioni di accesso di quest’ultimo e permettergli di eseguire determinate azioni, la sicurezza ricopre un ruolo fondamentale. Il consiglio è quindi quello di salvare le sessioni su database, creando una semplice tabella (ad esempio per MySql):
CREATE TABLE IF NOT EXISTS  `ci_sessions` ( 
session_id varchar(40) DEFAULT '0' NOT NULL, ip_address varchar(16) 
DEFAULT '0' NOT NULL, user_agent varchar(50) NOT NULL, last_activity 
int(10) unsigned DEFAULT 0 NOT NULL, user_data text NOT NULL, PRIMARY 
KEY (session_id) );
Comunichiamo ora a Codeigniter che le sessioni dovranno basarsi sulla tabella appena creata:
$config['sess_use_database'] = TRUE;
$config['sess_table_name'] ='ci_sessions';
Bisogna tenere bene a mente il funzionamento della sessione: dopo un tempo definito il sistema ricreerà il session_id e aggiornerà data e ora dell’ultima attività (il timestamp visto in precedenza). L’intervallo predefinito per questo aggiornamento è 5 minuti, ma può essere modificato.

Inizializzare e distruggere una sessione

Possiamo caricare manualmente la libreria di sessione usando il comando:
$this->load->library('session');
Per distruggere una sessione, usiamo:
$this->session->sess_destroy();

Interagire con le sessioni

Scrivere una variabile di sessione è possibile mediante una specifica funzione della classe Session:
//Singola variabile
$this->session->set_userdata('some_name', 'some_value');

//Più variabili in una volta sola con array associativo
$newdata = array(
                   'username'  => 'johndoe',
                   'email'     => 'johndoe@some-site.com',
                   'logged_in' => TRUE
               );

$this->session->set_userdata($newdata);
Per ottenere una delle variabili di sessione impostate in precedenza:
$username = $this->session->userdata('username');
Infine, per cancellare una variabile di sessione (ad esempio username):
$this->session->unset_userdata('username');

Flashdata: un tipo particolare di sessione

Una variabile flashdata può essere letta solo una volta, poiché alla lettura la variabile viene eliminata. Molto spesso viene usata per i vari messaggi di errore o di feedback positivo (ad esempio "Operazione completata con successo"). Una variabile di questo tipo si imposta con la funzione:
$this->session->set_flashdata('item', 'value');
E si legge (ricordate bene: una sola volta, dopodiché la variabile sarà cancellata) con il comando
$this->session->flashdata('item');

Download assistito di file

Codeigniter offre un comodo strumento per forzare il download di un determinato file da parte di un utente. Per prima cosa, bisogna caricare l'helper adatto:
$this->load->helper('download');
Ed utilizzare la funzione apposita, con il seguente formato
force_download('filename', 'data')
Questa funzione genera automaticamente gli header http necessari per forzare un download all’utente. Il primo parametro è il nome che si vuol dare al file da salvare, il secondo parametro sono i dati che si vogliono far scaricare. Quest’ultimo parametro deve essere sempre una stringa; bisogna quindi caricare il contenuto di un file come stringa per effettuarne il download. Vediamo qualche esempio:
$data = 'Here is some text!';
$name = 'mytext.txt';

force_download($name, $data);
Il seguente codice è necessario nel caso di un file esistente:
// Leggo tutto il contenuto del file
$data = file_get_contents("/path/to/photo.jpg");
$name = 'myphoto.jpg';

force_download($name, $data);

Prima parte della guida: Guida Codeigniter 1 - Introduzione
Seconda parte della guida: Guida Codeigniter 2 - Primi passi
Quarta parte della guida: Guida Codeigniter 4 - Gestione del multilingua

EDIT:
Ho pubblicato la guida in formato PDF contenente tutti gli argomenti affrontati sul blog, liberamente scaricabile e stampabile. La trovate al link:
http://stefanobianchini.blogspot.it/2012/11/guida-codeigniter-modo-mio-pdf-in.html

Guida Codeigniter 2 - Primi passi

Primi passi con Codeigniter

Controller

I Controllers, come già detto, sono la parte fondamentale del software strutturato con il framework CodeIgniter. Il tutorial della documentazione ufficiale li definisce la colla della web application. Cerchiamo di comprendere meglio la logica di funzionamento: quando viene fatta una richiesta del tipo
http://localhost/index.php/news/view/12
il framework elabora la richiesta in questo modo:
http://localhost/index.php/<controller>/<metodo>/<parametri>
richiedendo l’esecuzione del metodo "view" con parametro "12" al controller denominato "news". Questo significa che, per far funzionare la richiesta GET specificata, deve essere implementato un controller news.php sotto la cartella application/controllers, con il seguente contenuto:
<?php
    class News extends CI_Controller {
        public function view($id)
        {
                //qui codice per fare qualcosa
        }
        public function index()
        {
                //qui codice per fare qualcosa
        }
}
Capendo questo meccanismo, si è a buon punto nella comprensione di CodeIgniter; bisogna smettere di ragionare in termini di files php e iniziare a spostare l'attenzione su controllers e metodi. Anche se inizialmente sembra complicato, in realtà questo modo di strutturare l’applicazione porta enormi vantaggi.
Non preoccupiamoci, per il momento, del poco estetico "‘index.php"’ all’interno dell’Url che stiamo considerando: con una semplice configurazione può essere eliminato, risultando molto più facile da leggere sia per i motori di ricerca sia per gli esseri umani. Cerchiamo ora di analizzare questo codice, comprendendo la logica base del framework. Per prima cosa un controller deve essere definito come classe Php che estende CI_Controller e deve essere chiamato con lo stesso nome del file (senza l'estensione .php, ma con la prima lettera maiuscola, news.php diventa News). All’interno della classe notiamo un metodo pubblico (view) che accetta un parametro ($id). Come già scritto, il sistema andrà a richiamare il metodo view con il parametro passato (12) ricercandolo all’interno del controller news. In caso di più parametri, basta separarli con il carattere "/" slash.
Il metodo "index" non è obbligatorio, tuttavia ha il ruolo di gestire le richieste generiche al controller, cioé non specificando metodo né parametri:
http://localhost/index.php/news
Ricordiamo è compito del controller fare da tramite tra l’elaborazione dei dati e la visualizzazione degli stessi; il che significa che, una volta eseguite determinate operazioni sui dati, deve caricare un altro mattone fondamentale: la vista (view). Per questo motivo il codice visto in precedenza viene così modificato: ,
public function view($id)
{
        $data['id'] = $id;
        $this->load->view('news/view', $data);
}
public function index()
{
        $this->load->view('news/index');
}
La prima funzione ha due istruzioni, che servono per inserire all’interno di un array il contenuto della variabile $id e per caricare in memoria una vista posizionata sotto /application/views/ news/view.php passando il suddetto array. Traspare già il modo per passare dei dati alla vista specificata, in modo che la vista li possa mostrare (vedremo poi in che modo). Da notare che tutte le viste vengono ricercate nella directory /application/views al cui interno possono esistere sottocartelle (news ne è un esempio) che contengono le viste di categorie simili, in questo caso tutte le viste utilizzate dal controller news. La vista deve essere specificata senza l'estensione .php tramite il comando ,
$this->load->view('nomeDellaVista',$eventualeArrayDaPassare);

View

Nel paragrafo precedente abbiamo visto come caricare una vista da un controller, funzione fondamentale per il corretto di una web application con il framework CodeIgniter. Ma come deve essere strutturata una vista? Rispolverando l’esempio precedente, nella directory che contiene le view (application/views) deve essere creata una sottocartella news, che conterra due viste:
  • view.php
  • index.php
che corrispondono alle viste caricate in precedenza nel codice del controller. Analizziamo ora il contenuto della vista view.php, che e semplicemente HTML con l’aggiunta di codice Php dove necessita
<html>
<head>
<title>CodeIgniter a modo mio - Esempio di Vista</title>
</head>
<body>
<h1>
Hai specificato il parametro id impostandolo al valore <?php echo $id; ?> </h1>
</body>
</html>
Il concetto chiave per il passaggio dei dati da un controller ad una view è il seguente: passando un array del tipo $data['qualcosa'], accederò ai dati dalla view interagendo con la variabile $qualcosa. Nel caso del nostro esempio, $data['id'] diventa $id all’interno della vista. La vista mostra i dati elaborati dal controller; il controller a sua volta accede ai dati attraverso un modello, anche se non è espressamente richiesto dal framework, ma fortemente consigliato dal pattern MVC.

Caricamento di più viste

È buona prassi in una applicazione web complessa suddividere le viste creando un header ed un footer uguali per tutte le pagine. Come è possibile in CodeIgniter fare una cosa del genere, come si possono caricare più viste da un controllore? Semplicemente chiedendo di caricarle una di seguito all'altra:
$this->load->view('header');
$this->load->view('example_view', $data);
$this->load->view('footer');

Model

Il Model si occupa dell’interazione con i dati, offre sostanzialmente al controller un approccio ad un livello più astratto delle semplici interrogazioni su database. Ad esempio, per gestire un motore di news, un modello potrebbe avere il seguente scheletro:
//news_model.php
class News_model extends CI_Model {
        function __construct()
        {
                // Richiamo del costruttore parent
                parent::__construct();
                $this->load->database();
        }
        function get_latest_news()
        {
                // qui codice
        }
        function insert($data)
        {
                // qui codice
        }
        function update($news_id, $data)
        {
                // qui codice
        }
}
Un modello è una classe che estende CI_Model (base Model class), il cui nome deve essere lo stesso del file posizionato sotto application/models/ e deve avere la prima lettera maiuscola. Il modello deve quindi venire caricato dal controller, il quale ne eseguirà le funzioni per accedere ai dati (nell’esempio, get_latest_news, insert o update). Nel costruttore del modello si può notare il caricamento del database
$this->load->database();
fondamentale per accedere ai dati.

Caricare un modello

Il controller, come già scritto, deve caricare il modello: questo può essere fatto attraverso il comando
$this->load->model('News_model');
che permette di caricare in una variabile con lo stesso nome del modello (nell’esempio, $News_model) e quindi di poter interagire con essa:
$this->News_model->get_latest_news();

Helpers

I programmatori nostalgici del periodo precedente il passaggio del Php ad una struttura Object Oriented non potranno che essere entusiasti degli Helpers. Gli Helpers, come suggerisce il nome stesso, sono degli aiutanti che offrono delle funzioni per le operazioni più comuni. Avete capito bene, funzioni, non classi. Semplici funzioni Php. Un Helper va caricato con la seguente sintassi:
$this->load->helper('nome_helper');

Parametri di input

Per gestire al meglio i parametri GET, POST o COOKIE CodeIgniter mette a disposizione una comoda classe che si preoccupa di mettere in sicurezza le variabili al posto nostro e offre un insieme di funzioni quali capire lo user agent utilizzato, scoprire se e una richiesta ajax, catturare l’indirizzo ip dell’utente (per informazioni vedi questo indirizzo). Di seguito sono mostrate le funzioni fondamentali della classe input:
$this->input->post('some_data')
se $_POST['some_data'] è impostato ritorna il valore, FALSE altrimenti
$this->input->get('some_data')
se $_GET['some_data'] è impostato ritorna il valore, FALSE altrimenti
$this->input->cookie('some_data')
se $_COOKIE['some_data'] è impostato ritorna il valore, FALSE altrimenti
$this->input->server()
ricerca nell'array globale $_SERVER
$this->input->get_post('some_data')
ricerca sia nelle variabili post che in quelle get
$this->input->set_cookie()
indispensabile per impostare un cookie
$cookie = array(
'name' => 'The Cookie Name',
'value' => 'The Value',
'expire' => '86500',
'domain' => '.some-domain.com',
'path' => '/',
'prefix' => 'myprefix_',
'secure' => TRUE
);
$this->input->set_cookie($cookie);

Prima parte della guida: Guida Codeigniter 1 - Introduzione

EDIT:
Ho pubblicato la guida in formato PDF contenente tutti gli argomenti affrontati sul blog, liberamente scaricabile e stampabile. La trovate al link:
http://stefanobianchini.blogspot.it/2012/11/guida-codeigniter-modo-mio-pdf-in.html

venerdì 19 ottobre 2012

Guida Codeigniter 1 - Introduzione

Perché CodeIgniter

Arriva un momento, nel percorso lavorativo di un programmatore Php, nel quale si avverte la mancanza di un sostegno che possa semplificare la creazione e la gestione di progetti complessi.
Questa sensazione porta alla ricerca dei cosiddetti framework, ossia particolari strumenti che permettono di velocizzare determinate operazioni di uno sviluppatore, aiutandolo anche (nei limiti del possibile) ad evitare gli errori più comuni durante la progettazione e la stesura del codice. I framework contengono metodi e funzioni in risposta ai problemi più comuni; permettono di interagire facilmente con vari tipi di database e supportano una caratteristica importante, la scalabilità.
Codeigniter è un framework, perfetto a mio modo di vedere, per chi ha il bisogno di avere il pieno controllo del proprio codice Php e necessita però di scorciatoie per le operazioni più comuni. Vediamo qualche caratteristica di Codeigniter così come vengono pubblicizzate sul sito del progetto:
  • leggerezza - possiede senza dubbio un core di piccole dimensioni, ma in grado di fare grandi cose;
  • ottime prestazioni;
  • ampia compatibilità con i vari servizi di hosting, a prescindere dalle versioni (dalla 5.1.6 in avanti) e configurazioni del motore Php;
  • già funzionante senza configurazioni - appena scaricato il framework non necessita di configurazioni particolari, a meno ovviamente delle impostazioni del database;
  • non necessita di essere eseguito da linea di comando (al contrario di simphony);
  • non necessita che lo sviluppatore impari un linguaggio di templating (ne supporta uno ma è assolutamente opzionale);
  • ha una ottima documentazione - e migliaia di risposte già pronte in caso di problemi.
A queste caratteristiche, che dovrebbero convincere un programmatore php ad adottare Codeigniter, aggiungo le funzionalità che possiede, per me fondamentali per comprenderne appieno le potenzialità:
  • pieno supporto di MySQL (4.1+), MySQLi, MS SQL, Postgres, Oracle, SQLite, and ODBC;
  • interazione diretta con i database o mediante quello che viene chiamato Active Record;
  • costringe a sviluppare seguendo il pattern MVC, il quale a mio avviso aiuta sia durante la progettazione che durante eventuali modifiche al software;
  • genera URL facilmente leggibili dai motori di ricerca (SEO friendly), ad esempio
    http://www.example.com/news/view/12
  • è facilmente personalizzabile ampliandone le potenzialità;
  • supporta un sistema di internazionalizzazione (multilingua). 

Flusso di funzionamento


Quello che uno sviluppatore, abituato a interagire con i files php atti ad una determinata funzione (ad esempio news.php, contact.php ecc) deve capire è la centralità del file index.php, vero e proprio “vigile urbano” di un progetto codeigniter. Non esistono altre pagine all’infuori di index.php nella root principale, ma come si vedrà successivamente tutte le pagine necessarie saranno “controllori” (application controller) seguendo il pattern MVC. Dopo questa precisazione risulta più comprensibile il flusso di funzionamento mostrato in figura:
  1. La pagina index.php è quella principale, fulcro del sistema, che inizializza le risorse utilizzate da CodeIgniter
  2. Una funzionalità di routing (personalizzabile e modificabile) analizza la richiesta HTTP per determinare il comportamento che il sistema deve adottare.
  3. Se un sistema di caching è abilitato e viene trovato il file richiesto in cache, allora si evita la normale esecuzione del file velocizzando il sistema.
  4. La richiesta HTTP è filtrata per evitare problemi di sicurezza, prima che qualsiasi application controller sia eseguito.
  5. Il Controller carica i modelli, le librerie del core principale, e tutte le risorse necessarie a processare la specifica richiesta. Nel controller risiede, per farla breve, la funzionalità che il programmatore vuole implementare.
  6. Viene caricata (dal controller) la Vista, ossia il codice HTML che deve essere mostrato nel browser dell’utente finale. Se il caching è abilitato, la pagina viene salvata in cache per un eventuale richiesta futura. 

Il pattern Model View Controller

Il pattern MVC viene utilizzato sempre più frequentemente e il suo principale vantaggio, applicato al php, è quello di separare l’interazione coi i dati e l’interfaccia grafica. Vediamo nel dettaglio:
  • il model fornisce i metodi per interagire con i dati utili all’applicazione;
  • il view visualizza i dati contenuti nel model: normalmente è una pagina web in html;
  • il controller è l’intermediario tra le due entità precedenti e racchiude l’elaborazione dei dati (ossia una volta ottenuti i dati con il Model, li elabora e li passa al View).

Installazione e configurazione

Come menzionato in precedenza, l’installazione e la configurazione di questo framework sono operazioni molto semplici e veloci. Dopo averne scaricato l’ultima versione disponibile dal sito codeigniter, si scompatta l’archivio nella cartella del web server preposta allo scopo, ad esempio la directory root, htdocs per Apache.
Per la configurazione è sufficiente aprire il file
application/config/config.php
ed impostare la variabile di configurazione base_url con l’Url base della vostra applicazione web, ad esempio: ,
$config['base_url']='http://localhost/';
Da notare il fatto che se viene lasciata vuota, CodeIgniter tenterà di comprendere questo parametro da solo (spesso funziona anche se lasciato vuoto).
Basterà aprire a questo punto tramite un browser l’indirizzo specificato come Url base e il sistema vi darà il benvenuto:

Un’occhiata alla struttura

Di base, CodeIgniter ha tre cartelle principali:
application
che conterrà tutto ciò che lo sviluppatore deve implementare (controllori, modelli, viste, librerie di terze parti eccetera); di tutte le sue sottocartelle, per il momento suggerisco di notare le cartelle fondamentali, ossia config, controllers, models e views.
system
che contiene il cuore del framework.
user_guide
che può essere eliminata poiché contiene la versione offline della documentazione.
Consiglio di creare una terza cartella, chiamata assets, che conterrà gli script Javascript, i fogli di stile CSS e le immagini di cui l’applicazione avrà bisogno.


Seconda parte della guida: Guida Codeigniter 2 - Primi passi
Terza parte della guida: Guida Codeigniter 3 - Uso avanzato
Quarta parte della guida: Guida Codeigniter 4 - Gestione del multilingua

EDIT:
Ho pubblicato la guida in formato PDF contenente tutti gli argomenti affrontati sul blog, liberamente scaricabile e stampabile. La trovate al link:
http://stefanobianchini.blogspot.it/2012/11/guida-codeigniter-modo-mio-pdf-in.html