ExtJs – Integrazione tra PHP e ExtJS con JSON

PHPExtJs (oggi Sencha) è uno dei principali framework javascript attualmente disponibili: è potente, flessibile, cross-platform, ed è probabilmente uno degli strumenti più veloci per realizzare rich internet applications. In questo articolo vedremo i concetti principali che permettono di integrare ExtJs in una web application PHP-based attraverso il protocollo JSON.

JSON (JavaScript Object Notation) è un formato di interscambio dati: è molto leggero e semplice da scrivere e leggere per l’uomo. E’ un formato testuale completamente indipendente, che segue poche semplici convenzioni familiari ad esempio a chi programma in Java, Javascript, Perl, ecc. Per ulteriori informazioni è disponibile il sito di riferimento.

ExtJs permette con poche righe di codice di creare finestre, griglie, grafici, layout complessi, e molto altro ancora. Per gestire la maggior parte delle strutture complesse come ad esempio le griglie o i grafici, ExtJs utilizza il concetto di “store”. Lo store possiamo immaginarlo come una sorta di database locale, nel quale vengono memorizzati tutti i dati principali: come quelli da rappresentare e quelli relativi alla struttura grafica. Lo store è la sorgente dei dati, il luogo da dove provengono i dati che popolano questi oggetti complessi: è qui dunque, nello store, che dobbiamo inserire i dati da dare in pasto a ExtJs per la rappresentazione.

Il ciclo che avviene è sostanzialmente questo:

  1. Attraverso PHP recuperiamo i dati ad esempio dal database
  2. Manipoliamo questi dati in modo da renderli leggibili e scrivibili nello store di ExtJs
  3. Utilizziamo JSON per passare i dati a ExtJs
  4. ExtJs visualizzerà i dati in questione

Supponiamo dunque di partire con una variabile PHP in cui è contenuto il result set di una query:


$result = mysql_query($query);
$data = array();
while ( $row = mysql_fetch_assoc($result) ) {
array_push( $data, array(
'recordID' => $row['Id'],
'titolo' => $row['titolo'],
'descrizione' => $row['descrizione'],
));
}
$store = json_encode($data);

In questo codice c’è il cuore del funzionamento di questo meccanismo. “$data” rappresenta i dati preparati, quelli che verranno inseriti nello store e rappresentati da ExtJs. Come vengono preparati questi dati? Nella prima riga di codice recuperiamo il result set dei dati che vogliamo rappresentare e lo salviamo nella variabile “$resultset”.

Eseguiamo poi un ciclo, nel quale per ogni record del result set creiamo un array con i dati di ogni record, nello specifico un array associativo. Attenzione: questo è un punto fondamentale. Le chiavi dell’array associativo devono corrispondere a quelle che caratterizzato la struttura dello store, come vedremo tra un attimo.

L’ultima riga di codice crea la stringa JSON che potrà essere data in pasto allo store di ExtJs, stringa che viene creata attraverso la funzione di PHP json_encode(), disponibile nelle estensioni ufficiali (PECL).

Veniamo alla definizione dello store. Prendiamo un esempio tra i tanti disponibili sul sito ufficiale di ExtJs; come possiamo vedere nel codice sorgente della pagina, lo store per il pannello del grafico è così definito:

var store = new Ext.data.JsonStore({
fields:[‘id’, ‘titolo’, ‘descrizione],
data: [
{name:’Jul 07′, visits: 245000, views: 3000000},
{name:’Aug 07′, visits: 240000, views: 3500000},
{name:’Sep 07′, visits: 355000, views: 4000000},
{name:’Oct 07′, visits: 375000, views: 4200000},
{name:’Nov 07′, visits: 490000, views: 4500000},
{name:’Dec 07′, visits: 495000, views: 5800000},
{name:’Jan 08′, visits: 520000, views: 6000000},
{name:’Feb 08’, visits: 620000, views: 7500000}
]
});

Noi però vogliamo che i dati siano generati dinamicamente, dunque apportiamo la seguente modifica:

var store = new Ext.data.JsonStore({
fields:[‘id’, ‘titolo’, ‘descrizione],
data: < ?php echo $store; ? >
});

Come ho indicato poc’anzi, i campi che definiscono lo store sono uguali alle chiavi dell’array associativo che ho creato nei passi precedenti. In questo modo è possibile creare le associazioni tra i campi dello store e i valori che abbiamo recuperato dal database.

Abbiamo visto come creare un collegamento tra PHP e ExtJs attraverso JSON: questo meccanismo vale per tutti i componenti complessi di ExtJs, ovvero quelli che sono predisposti per ricevere dati attraverso un flusso JSON.

16 commenti su “ExtJs – Integrazione tra PHP e ExtJS con JSON”

  1. Ciao GeorgeB,

    ho pubblicato un articolo su come impostare un layout complesso con un TreePanel ed un Panel, lo trovi qui.

    Fammi sapere se ti torna utile! 😉

  2. Ciao! 🙂

    ..perchè no! Appena riesco provo a scrivere un articolo su una struttura complessa in ExtJs: non so se in un solo articolo riesco a farci stare tutto l’argomento, ma vediamo che ne esce! 😉

  3. Ciao!!
    sono sempre io 🙂

    non è che per caso hai in programma di scrivere un articolo su comer realizzare una struttura del tipo:

    parte sinistra un menu ad albero e quando clicchi sul nodo, viene caricato un form nella parte centrale..

    (tipo la documentazione di extjs). non saprei prorpio da dove cominciare 🙁

    Saluti!!!

  4. in questo caso dipende molto da quello che devi fare: normalmente, per una questione di performance, sarebbe sicuramente meglio gestire componenti ExtJs, in modo da evitare di caricare altre pagine.

    Nel tuo caso però stiamo parlando di un pannello di login, quindi un redirect su un’altra pagina ci sta benissimo.

    Dipende da come hai strutturato il codice, l’ideale sarebbe un redirect lato server con la funzione “header()”, ma probabilmente la cosa più semplice è reindirizzare la pagina con la funzione “location” di javascript chiamata nella parte “success” del form; il caso di errore lo puoi far gestire invece dalla parte “failure” del form.

  5. il codice che hai postato funziona perfettamente!
    ho usato nella pagina php (credo sia uguale) questa notazione:
    [php]
    $risp = array( "success"=>true);
    echo json_encode($risp);
    [/php]
    Ho letto da qualche parte che le web-application, non dovrebbero richiamare nuove pagine, ma visualizzare nella stessa, nuovi componenti EXT a seconda delle operazioni effettuate.

    Per esempio, io al momento nella pagina login.php effettuo la connessione la databese. Se l’utente è verificato, vorrei andare in nuova pagina, o comunque far vedere nuove informazioni.

    Come mi consigli di organizzare la struttura??
    Grazie Ancora!!

  6. ah dimenticavo: se adotti la situazione precedente, nel file “login.php”, dopo aver eseguito tutto le varie operazioni, manderai il risultato di feedback in questo modo:

    SUCCESSO

    [php]
    $response = array("success" => true);
    $this->_helper->json($response);
    [/php]

    INSUCCESSO

    [php]
    $response = array("success" => false);
    $this->_helper->json($response);
    [/php]

    in questo modo comunicherai al form il risultato delle richiesta, e verrà eseguita l’azione che corrisponde al risultato successo/insuccesso! 😉

  7. ok, qui dipende come vuoi gestire il feedback ed anche in parte da cosa fa la pagina “login.php”. Se vuoi gestirlo con ExtJs, lì dove abbiamo definito la gestione del submit del form, potresti fare una cosa del genere:

    [javascript]
    onSubmitBtnClick: function() {

    Ext.getCmp(‘form_test’).getForm().submit({

    waitMsg:’Saving Data…’,
    success: function(a, b) {

    //fai qualcosa nel caso tutto sia andato a buon fine
    },
    failure: function(a, b) {

    Ext.MessageBox.show({
    title: ”,
    msg: "Impossibile effettuare il login",
    buttons: Ext.MessageBox.OK,
    icon: Ext.MessageBox.ERROR
    });

    }

    });
    }
    [/javascript]

  8. Ciao,
    sono riuscito a fare il tutto seguendo quanto mi hai detto.
    ore però mi servirebbe un ulteriore consiglio 🙂

    Nella url richiamata, a secondo se viene effettuato il login oppure no, come faccio a ritornare il feedback nella prima pagina?

    grazie ancora..

  9. prova così:

    [javascript]
    MyForm = Ext.extend(MyFormUi, {
    initComponent: function() {
    MyForm.superclass.initComponent.call(this);
    this.submitBtn.on(‘click’, this.onSubmitBtnClick, this);
    },
    onSubmitBtnClick: function() {
    Ext.getCmp(‘form_test’).getForm().submit();
    }
    });

    MyFormUi = Ext.extend(Ext.form.FormPanel, {
    title: ‘Form Login’,
    id: ‘form_test’,
    url: ‘login.php’,
    width: 310,
    height: 135,
    padding: 10,
    layout: ‘absolute’,
    initComponent: function() {
    this.items = [
    {
    xtype: ‘textfield’,
    x: 120,
    y: 10,
    width: 180,
    name: ‘user’,
    id: ‘user’
    },
    {
    xtype: ‘label’,
    text: ‘Utente:’,
    x: 20,
    y: 10,
    width: 70
    },
    {
    xtype: ‘label’,
    text: ‘Password:’,
    x: 20,
    y: 40
    },
    {
    xtype: ‘textfield’,
    x: 120,
    y: 40,
    width: 180,
    name: ‘pass’,
    inputType: ‘password’,
    id: ‘pass’
    },
    {
    xtype: ‘button’,
    text: ‘Login’,
    x: 250,
    y: 70,
    width: 50,
    type: ‘submit’,
    ref: ‘submitBtn’,
    id: ‘login’
    }
    ];
    MyFormUi.superclass.initComponent.call(this);
    }
    });
    [/javascript]

  10. queste sono le pagine che mi ha generato ExtJS:

    [javascript]
    MyForm = Ext.extend(MyFormUi, {
    initComponent: function() {
    MyForm.superclass.initComponent.call(this);
    this.submitBtn.on(‘click’, this.onSubmitBtnClick, this);
    },
    onSubmitBtnClick: function() {
    //alert ("prova");
    url : ‘login.php’;
    }
    });

    MyFormUi = Ext.extend(Ext.form.FormPanel, {
    title: ‘Form Login’,
    width: 310,
    height: 135,
    padding: 10,
    layout: ‘absolute’,
    initComponent: function() {
    this.items = [
    {
    xtype: ‘textfield’,
    x: 120,
    y: 10,
    width: 180,
    name: ‘user’,
    id: ‘user’
    },
    {
    xtype: ‘label’,
    text: ‘Utente:’,
    x: 20,
    y: 10,
    width: 70
    },
    {
    xtype: ‘label’,
    text: ‘Password:’,
    x: 20,
    y: 40
    },
    {
    xtype: ‘textfield’,
    x: 120,
    y: 40,
    width: 180,
    name: ‘pass’,
    inputType: ‘password’,
    id: ‘pass’
    },
    {
    xtype: ‘button’,
    text: ‘Login’,
    x: 250,
    y: 70,
    width: 50,
    type: ‘submit’,
    ref: ‘submitBtn’,
    id: ‘login’
    }
    ];
    MyFormUi.superclass.initComponent.call(this);
    }
    });
    [/javascript]
    più una pagina html e un’altra pagina js in cui visualizzo l’oggetto.

    grazie mille!!

  11. mmm… non riesco a chiamare la pagina login.php (dove ho solo al momento, messo una echo “prova”;)
    [php]
    onSubmitBtnClick: function() {
    //alert (“Prova”);
    url : ‘login.php’;
    }
    [/php]

    la finetra alert funziona correttamente, ma se lascio solo la stringa url : ‘login.php’; quando clicco sul bottone non succede nulla.

  12. Innanzitutto una precisazione: nel commento precedente mi sono confuso, non è “data” che potresti usare, bensì “params”; ad ogni modo nel tuo caso non è necessaria. 😉

    Come hai fatto va bene, devi però aggiungere la proprietà “id” per ogni campo del form:

    [php]
    [..]

    {
    xtype: ‘textfield’,
    x: 120,
    y: 10,
    width: 180,
    id: ‘user’,
    name: ‘user’
    }

    [..]

    {
    xtype: ‘textfield’,
    x: 120,
    y: 40,
    width: 180,
    id: ‘pass’,
    name: ‘pass’,
    inputType: ‘password’
    },

    [..]
    [/php]

    A questo punto quando esegui il submit del form, verranno inviati alla pagina “login.php” le variabili “user” e “pass”, attraverso il metodo GET (dovrebbe essere il metodo di default)…sarà sufficiente recuperare tali parametri in “login.php”attraverso il $_GET[]:

    [php]
    [..]
    $username = $_GET[‘user’];
    $pass = $_GET[‘pass’];
    [..]
    [/php]

    Prova a vedere se riusci a stampare a video da “login.php” i valori che inserisci nel form; se tutto funziona, dovrai ancora fare alcune cosette:

    1) controllare e “normalizzare” il campo username per prevenire problemi di sicurezza

    2) crittografare la pass per evitare di trasmetterla in chiaro

    3) restituire un corretto feedback all’utente (lo puoi fare sia in PHP che con ExtJs, dipende da come strutturi l’azione di “login effettuato con successo”)

  13. Grazie della risposta.
    all’interno del form non trovo la prorieta data ;(
    [php]
    MyFormUi = Ext.extend(Ext.form.FormPanel, {
    url:’login.php’, ——–"ho aggiunto questa riga"
    title: ‘Form Login’,
    width: 310,
    height: 135,
    padding: 10,
    layout: ‘absolute’,
    initComponent: function() {
    this.items = [
    {
    xtype: ‘textfield’,
    x: 120,
    y: 10,
    width: 180,
    name: ‘user’
    },
    {
    xtype: ‘label’,
    text: ‘Utente:’,
    x: 20,
    y: 10,
    width: 70
    },
    {
    xtype: ‘label’,
    text: ‘Password:’,
    x: 20,
    y: 40
    },
    {
    xtype: ‘textfield’,
    x: 120,
    y: 40,
    width: 180,
    name: ‘pass’,
    inputType: ‘password’
    },
    {
    xtype: ‘button’,
    text: ‘Login’,
    x: 250,
    y: 70,
    width: 50
    }
    ];
    MyFormUi.superclass.initComponent.call(this);
    }
    });
    [/php]

  14. Grazie per i complimenti! 😉

    Allora, nel codice del form dovresti avere una proprietà chiamata “formUrl”, questa la devi impostare in modo che punti ad una pagina php, es. form.php: questa sarà la pagina in cui ad esempio mettersi la connessione al db.

    In form.php userai la funzione json_decode per recuperare i dati inviati da extjs; per inviare i dati, sempre nel form,dovresti poter configurare la proprietà “data”,che puoi utilizzare per personalizzare i parametri..altrimenti, come ogni form normale, in form.php verranno inviati automaticamente tutti i campi contenuti nel form extjs. In pratica il segreto è la funzione json_decode, che ti permette di recuperare i parametri inviati dal form sotto forma di stringa json.

    Fai una prova, se hai problemi..sono qui! 😉

  15. Ciao!
    tra i vari articoli che ho letto, sicuramente questo è il più chiaro di tutti!!
    io sono alle prime armi.. potresti darmi qualche dritta :

    ho creato un semplice form con EXTJS in cui si puo inserire utente e pass.
    quando ho esportato il progetto mi ha questi file:

    MyForm.js
    MyForm.ui.js
    xds_index.js
    xds_index.html

    ora però vorrei che quando inserirsco utente e pass, e clicco su connect, effettuo le mio operazione per connettermi al databesa mysql.
    Su quale pagina devo andare a scrivere codice ?
    e soprattutto.. come faccio a prendere il contenuto dei campi e passarmelo in var php per connettermi.

    Grazie mille!!!!

I commenti sono chiusi.