N0811_PHP.qxp 23-10-2008 12:44 Pagina 44 ■ PHP PHP ovvero come ti trasformo facilmente l’antico in moderno I criteri di business cambiano velocemente e stare al passo con i tempi diventa un’esigenza fondamentale. Ecco un contributo pratico su come sia possibile modernizzare le applicazioni, senza per questo dover buttare il bambino con l’acqua sporca Di Gianluca Gimigliano, Davide Sinicato e Paolo Boraschi I listati sono disponibili, in formato testo (.txt), in allegato alla versione elettronica dell’articolo I l dibattito sulla modernizzazione in ambiente AS/400 – IBM i è molto acceso e poiché se ne parla sempre più insistentemente significa che il tema è davvero importante. Operare con strumenti flessibili e d’avanguardia è indispensabile per rispondere alle sfide contemporanee, ma anche a porre le basi per quelle future. Migliorare l’accesso alle informazioni e la relativa presentazione è un obiettivo da perseguire. Le procedure di inserimento dati da parte degli utenti, la disponibilità di informazioni leggibili come ausilio per le decisioni del management, l’integrazione con clienti e fornitori, per esempio, sono tutte procedure che se sistematizzate in logica moderna portano a indiscussi vantaggi. Le modalità con cui si usufruiscono le applicazioni e la cosiddetta user experience sono fattori che facilitano e velocizzano il lavoro, e sappiamo bene quanto l’ottimizzazione dei tempi costituisca un profitto. Le nuove tecnologie forniscono gli strumenti concreti per attualizzare le logiche di business, ma spesso l’insofferenza al cambiamento preclude nuovi orizzonti e nuove opportunità. Mantenere le vecchie applicazioni con interfaccia a carattere (altresì conosciute come green screen) è più costoso che modernizzarle in termini di efficienza e leggibilità. Ma una cosa va detta chiaramente: modernizzazione non significa mettere in disparte il parco applicativo, ma valorizzarlo in chiave evoluta. System i è ancora efficiente, la sua solidità e la sicurezza del patrimonio delle informazioni sono punti fissi a cui è difficile rinunciare. Con questo articolo vogliamo portare il nostro contributo alla riflessione e sottolineare come le potenzialità di PHP siano una soluzione non onerosa per adattare le applicazioni legacy alle nuove esigenze. Tutto questo senza dover buttare gli investimenti o cambiare la logica di business. Abbiamo scelto un approccio pratico, sotto forma di tutorial, perché imparare facendo è il metodo migliore per immergersi da subito nell’operatività. La teoria è importante per astrarre, ma rispondere alla domanda: come accedere praticamente ai dati? è sicuramente più utile per sostenere il ragionamento. Distribuiremo i nostri interventi in tre puntate, ognuna di esse prenderà in esame un problema reale, lo analizzerà, e ne fornirà una risposta concreta. Perché PHP? PHP è un linguaggio giovane e maturo: è nato per rispondere alle logiche dell’era web, ma è già adottato in oltre 20 milioni di siti e spesso in applicazioni commerciali strategiche (Per 44 www.systeminews.it - www.hitechshop.it esempio in Italia è adottato da Fiat, Gavazzi Automation, Ministero dell’Interno, Banca Santander, Coop solo per citare alcuni casi significativi). PHP può contare su una vasta open community di sviluppatori, ma ha anche il sostegno di partner tecnologici di rilievo come IBM, Oracle, Adobe, MySQL e Microsoft che ne hanno intuito le potenzialità. PHP è facile e veloce: nasce come linguaggio procedurale, anche se comunque sfrutta completamente i modelli della programmazione a oggetti, e ciò non comporta ostacoli di apprendimento a chi opera con linguaggi strettamente legati alle applicazioni commerciali come RPG o COBOL. Lo sforzo è minimo rispetto ai risultati che si ottengono. Il tutorial L’importanza dei dati in ambiente System i è cruciale e la gestione ottimale con il database di riferimento è l’aspetto che cercheremo di evidenziare. Lo scopo di questi semplici esempi è quello di far risaltare come PHP permetta l’interazione con i dati di DB2 in modo nativo. PHP for i5/OS può essere installato direttamente sul sistema e sfruttare ibm_db2, una particolare estensione fornita da IBM, che è in grado di accedere nativamente a DB2 attraverso l’uso del linguaggio SQL. Tra linguaggio e database non c’è nient’altro che il sistema operativo e questo oltre che a essere una facilitazione logica è un enorme vantaggio in termini di prestazioni. La struttura del nostro tutorial si compone di tre semplici script (che pesano solo 4K l’uno commenti compresi!) e che sono la base di partenza da cui poi partire per costruire applicazioni sempre più sofisticate. I tre esempi che esamineremo sono: • • • cerca.php inserisci.php libreria.php Il Listato 1 presenta libreria.php, il nucleo della nostra applicazione, infatti è lo script che racchiude le funzioni di base per l’accesso al database di utilità definito dall’utente. Gli alti due moduli, inserisci.php (Listato 2) e cerca.php (Listato 3) fanno uso di questa libreria richiamandola all’inizio dello script mediante l’istruzione: SystemiNEWS - NOVEMBRE 2008 N0811_PHP.qxp 23-10-2008 12:44 Pagina 45 PHP ovvero come ti trasformo facilmente l’antico in moderno ■ Da notare che PHP incorpora lo script una sola volta anche se viene eseguita più volte la pagina: esso viene mantenuto in memoria fino al termine della sessione dello script stesso. L’assenza del percorso nel nome del file da includere può significare che si trova nella stessa cartella dello script chiamante, come nel nostro caso. Potrebbe essere collocato in una speciale cartella indicata attraverso la direttiva include_path compresa nel file di configurazione php.ini. Questo permette di proteggere informazioni delicate come i parametri di connessione al database in percorsi fuori dalla portata del web server. La connessione al database, forse la parte più delicata della nostra applicazione, viene effettuata tramite la funzione connetti(); l’accesso a DB2 avviene attraverso la sicurezza del sistema stesso, ossia con un utente e una password presenti nell’OS400. La funzione db2_connect esegue la reale connessione al database; si può osservare che devono essere indicati quattro parametri: • • • • nome del database; utente; password; opzioni di connessione. Uno degli errori più comuni è quello di indicare nel nome del database il valore “localhost”, oppure il nome System i o l’indirizzo IP dello stesso. L’informazione da fornire è invece quanto si ricava dal comando WRKRDBDIRE, questo è il CATALOG del nostro database System i e solitamente coincide con il nome del sistema, anche se, volendo, può essere modificato. Nel caso in cui la connessione fallisca, per esempio per l’indisponibilità del DB, l’esecuzione dello script viene terminata inviando un messaggio d’errore. In caso di successo, invece, la funzione restituisce la risorsa associata alla connessione al database. In PHP le risorse sono puntatori a connessioni fisiche (connessioni di rete, connessioni ai database, file aperti…) che non sono direttamente manipolabili se non attraverso opportuni comandi. Da notare la presenza dell’operatore @ che in PHP impedisce l’invio di messaggi d’errore da parte di comandi da esso preceduti, in modo da poterli personalizzare o visualizzare a seconda delle proprie scelte. Particolare attenzione va posta all’array opzionale che è il quarto parametro della connessione. Segnaliamo alcune “keyword” particolari che è importante conoscere: • • Listato 1 - libreria.php SystemiNEWS - NOVEMBRE 2008 i5_naming: può avere il valore DB2_i5_NAMING_OFF o DB2_i5_NAMING_ON. Ciò significa che l’eventuale qualificazione del file, o tabella nel linguaggio SQL, può avvenire con la sintassi LIB.FILE o LIB/FILE i5_lib: può contenere il nome di una current library che avremo sempre a disposizione durante tutta la connessione www.hitechshop.it - www.systeminews.it 45 N0811_PHP.qxp • 23-10-2008 12:44 Pagina 46 • DB2_i5_NAMING_OFF permette di accedere (in modo default) ai file (tabelle) presenti nella libreria indicata in i5_lib indipendentemente da quali siano le librerie presenti nella jobd dell’utente usato per il collegamento • DB2_i5_NAMING_ON, invece, non ci consentirà di indicare una particolare libreria current, ma avremo a disposizione tutto il path (la lista di librerie) dell’utente con cui abbiamo eseguito il collegamento al database db2_attr_case: impostato a DB2_CASE_LOWER ci consentirà utilizzare i nome dei campi del database del nostro sistema in minuscolo. Nota: avete mai provato a interfacciarvi da un applicativo esterno al database di System i? Il nome dei campi sono visti sempre tutti in maiuscolo. Se provate a portare su System i un progetto PHP, magari trovato in Internet, che è scritto per il classico ambiente LAMP (Linux, Apache, MySQL, PHP), noterete che tutti i campi scritti all’interno degli script sono minuscoli. Bene, db2_case_lower risolve questo problema. Lo script libreria.php contiene l’esecuzione delle istruzioni SQL, e a questo punto entrano in gioco db2_prepare e db2_execute. Queste due funzioni si usano congiuntamente, la prima serve per preparare il database a ricevere la nostra ricerca (la query in linguaggio SQL), mentre la seconda effettua l’esecuzione vera e propria. Tra l’esecuzione della prima e la seconda, volendo, può essere introdotta una funzione db2_bind_param che è utilizzata per formattare correttamente le variabili passate alla stringa SQL o, in caso di richiamo di store procedure, per immettere o ricevere dati dalle stesse. Nel nostro esempio queste funzioni sono state introdotte all’interno di una funzione personalizzata chiamata esegui_query() in modo da non dover essere riscritte ogni volta. Da notare che in caso d’errore la funzione restituisce una stringa con un messaggio, mentre nel caso opposto restituisce lo statement (di tipo risorsa). Questo è un esempio di sfruttamento virtuoso della non tipizzazione di PHP. Proseguendo nell’analisi del nostro script notiamo clean_campi_testo(). Questa funzione svolge un doppio ruolo: 1. ripulisce i valori che provengono dai campi testuali eliminando tutti gli spazi di troppo, anche tra le parole e formatta il contenuto in maiuscolo; 2. restituisce messaggi d’errore in caso il valore passato non sia compatibile con le condizioni imposte dagli altri parametri passati. Anche questa funzione restituisce un valore multiforme: un booleano false in assenza di errori, una stringa con il messaggio d’errore in caso contrario. Da notare il simbolo &, che definisce un passaggio di parametri per indirizzo; il suo scopo è quello di fare in modo che la pulizia applicata al parametro $valore si rifletta anche al di fuori della funzione. La funzione clean_prov() verifica la provincia inserita. A prima vista potrebbe sembrare superflua in quanto la scelta della provincia avviene attraverso un menu a tendina e quindi obbligata, ma uno dei divertimenti preferiti dagli hacker è mettere alla prova i siti web inviando dati nello stesso formato usato dai browser ma alterandone la forma dei campi (e quindi i possibili valori): la sicurezza è un aspetto da tenere sempre in considerazione, quindi è meglio non fidarsi mai dei dati provenienti dall’esterno. Listato 2 - inserisci.php 46 www.systeminews.it - www.hitechshop.it Sia inserisci.php (Listato 2) che cerca.php (Listato 3) contengono codice HTML e CSS (cascading Style Sheet – fogli di stile). È da notare come il codice PHP sia sempre separato nettamente dall’HTML che è esclusivamente utilizzato per aspetti di visualizzazione. SystemiNEWS - NOVEMBRE 2008 N0811_PHP.qxp 23-10-2008 12:44 Pagina 47 PHP ovvero come ti trasformo facilmente l’antico in moderno ■ Inserisci.php (Listato 2) è il modulo che permette la popolazione del database, per cui visualizza una semplice maschera HTML per l’inserimento dati. Una volta premuto il pulsante Inserisci, viene verificata la validità formale dei dati. Se corretti, controlla che non sia già presente un altro record con lo stesso valore di chiave primaria. Se tutte le verifiche hanno successo viene eseguita la query d’inserimento, altrimenti viene visualizzato un messaggio d’errore. Le primitive DB2 introdotte in questo script sono: • db2_fetch_assoc($stmt) che a partire da uno statement • $stmt relativo a una query di estrazione restituisce un array associativo legato al record corrente spostandosi poi al successivo; db2_close($conn) chiude la connessione $conn. Da notare che PHP al termine degli script, per impostazione predefinita, rilascia tutte le risorse tra cui anche le connessioni ai database, ma se non abbiamo bisogno di una connessione è meglio chiuderla il prima possibile in modo da alleggerire il carico di lavoro per il database server. Lo script cerca.php (Listato 3) funge da motore di ricerca interno, anch’esso in assenza di parametri visualizza semplicemente la maschera da compilare. La ricerca avviene per una parte della ragione sociale o per provincia. Ovviamente sono presenti tutte le verifiche del caso sull’inserimento. Peculiarità di questo script è la costruzione dinamica della condizione di filtraggio da inserire nella query sulla base di quali e quante chiavi siano state inserite. Il risultato della query viene estratto e trasformato in una tabella HTML con l’ausilio della funzione genera_corpo_tabella(). Anche in questo caso poniamo l’attenzione sul fatto che la tabella non viene direttamente visualizzata, ma memorizzata in una variabile e, solo dopo, nella sezione di visualizzazione, inviata al browser. Questo per attenersi alle buone pratiche di progettazione che specificano di separare la logica dalla visualizzazione. La primitiva introdotta in cerca.php è db2_escape_string($valore), la sua funzione è quella di effettuare la quotatura del valore passato per impedire conflitti tra eventuali apostrofi presenti nel valore con quelli propri di SQL. Conclusioni Solo tre script sono stati sufficienti per dimostrare come PHP sia efficace per risolvere ‘modernamente’ i problemi più classici della gestione dati in ambiente IBM i. Nel prossimo intervento arricchiremo i nostri esempi con nuove funzionalità. Andremo così a costruire una vera e propria applicazione completa. State sintonizzati. Listato 3 - cerca.php SystemiNEWS - NOVEMBRE 2008 Gianluca Gimigliano è formatore, consulente e Zend Certified Engineer PHP 5. [email protected] Davide Sinicato è Zend Senior Consultant per l’area IBM i. [email protected] Paolo Boraschi si occupa di editoria, divulgazione tecnologica e comunicazione in ambito ICT. [email protected] www.hitechshop.it - www.systeminews.it 47