Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1

    oracle database class in php

    Ciao, volevo chiedere un consiglio per una classe di gestionde del db che sto sviluppando:

    l'apertura e chiusura della connessione al db è meglio implementarla a livello di singola query o a livello di costruttore/distruttore della classe?

  2. #2
    l'apertura/chiusura della connessione è un'operazione molto onerosa e va gestita in maniera oculata. Da qui la scelta di usare

    - apertura/chiusura nei distruttori
    - uso di connection pool

    l'apertura/chiusura ad ogni query direi che sia un suicidio. Attenzione all'implementazione delle transaction
    IP-PBX management: http://www.easypbx.it

    Old account: 2126 messages
    Oldest account: 3559 messages

  3. #3
    In che senso "implementazione delle transaction" ? Le transazioni non posso implementarle nella stringa della query? con condizioni e rollback o commit programmati in PL SQL (Oracle)

    Posto la classe ipotetica, al fine di trovarne i difetti! Il problema che verifico è fino ad ora solo un Warning nel momento in cui effettuo un inserimento:

    Warning: oci_fetch(): ORA-24374: define not done before fetch or execute and fetch in .../dbManager.php on line ..(praticamente quando faccio la oci_fetch.
    ecco la classe:

    <?php

    class dbManager {


    // Definizione degli Attributi di classe

    private $dbh; // Connettore database
    private $dbUser; // Utente del database
    private $dbPwd; // Password utente
    private $dbName; // Nome del database
    private $charset; // Charset
    private $stat; // Statement per l'esecuzione della query

    // Metodo costruttore
    public function __construct(){

    // Valorizzo i dati per la connessione al database (ESEMPIO)
    $this->dbUser = 'xxxx';
    $this->dbPwd = 'yyyy';
    $this->dbName = 'wwww';
    $this->charset = 'zzzz';
    $this->dbOpenConn();
    }

    /*
    * ************************************************** ************
    *
    * METODI PRIVATI
    *
    * ************************************************** ************
    */

    // Metodo per connettersi al database
    private function dbOpenConn(){
    $this->dbh = oci_connect($this->dbUser,$this->dbPwd,$this->dbName,$this->charset);
    }

    // Metodo per disconnettere il database
    private function dbCloseConn(){
    oci_close($this->dbh);
    }

    // Metodo per fare il parsing della query
    private function dbParseQuery($query){
    $this->stat = oci_parse($this->dbh,$query);
    if (!$this->stat){
    echo oci_error($this->stat);
    exit();
    }
    }

    // Metodo per eseguire la query
    private function dbExecuteQuery(){
    if (!oci_execute($this->stat)){
    echo oci_error($this->stat);
    exit();
    }
    }

    // Metodo per il bind delle variabili
    private function dbBind($query,$params){

    $nomi = array();
    $valori = array();

    // Recupero i nomi e i valori delle variabili
    foreach ($params as $v_name => $v_value){
    $nomi[] = $v_name;
    $valori[] = $v_value;
    }

    // Eseguo il bind per ogni coppia nome->valore
    for ($i=0;$i<count($nomi);$i++)
    oci_bind_by_name($this->stat,$nomi[$i],$valori[$i]);

    }

    /*
    * Metodo per costruire l'array dei risultati in modo numerico.
    * Se il risultato è un insieme di record, si ha una matrice avente
    * tante righe quanti sono i risultati della query (da 0 a n-1).
    * Se il risultato è un solo record invece ritorna un array con i valori
    * risultanti
    */
    private function dbNumericResult(){
    // Uso un contatore per assegnare le righe
    $j = 0;

    $result = array();

    while (oci_fetch($this->stat)){

    // Ogni elemento dell'array è un array di posti pari al numero di colonne

    // Se ho una sola colonna carico l'array monodimensionale
    if (oci_num_fields($this->stat) == 1){
    $result[] = oci_result($this->stat,1);
    }

    // Se ho più di una colonna, uso un array bidimensionale
    else{

    // Per ogni colonna aggiungo aggiungo il valore ritornato dalla query
    for ($i=0;$i<oci_num_fields($this->stat);$i++){
    $result[$j][$i] = oci_result($this->stat,$i+1);
    }
    $j++;
    }
    }

    if (count($result) == 1)
    return $result[0];
    return $result;
    }

    /*
    * Metodo per costruire l'array associativo dei risultati
    * Se il risultato è un insieme di record, si ha una matrice in cui ogni riga
    * è rappresentata da un numero e ogni campo dal nome dello stesso. Se invece
    * si ha un unico record, il metodo ritorna un array associativo.
    */

    private function dbAssociativeResult(){

    $result = array();

    // Se seleziono una sola colonna ottengo un array numerico
    if (oci_num_fields($this->stat) == 1)
    while (oci_fetch($this->stat))
    $result[] = oci_result($this->stat,1);
    else{
    while ($result[] = oci_fetch_array($this->stat,OCI_ASSOC)){}

    /* L'ultima assegnazione è vuota perchè la condizione non si verifica
    * quindi tolgo l'ultimo elemento dall'array, altrimenti se ne conta
    * uno in più
    */
    unset($result[count($result)-1]);
    }

    if (count($result) == 1)
    return $result[0];
    return $result;
    }

    /*
    * ************************************************** ************
    *
    * METODI PUBBLICI
    *
    * ************************************************** ************
    */

    // Metodo per eseguire insert o update
    public function querySqlInsUpDel($query){

    // Parsing della query SQL
    $this->dbParseQuery($query);
    // Esecuzione della query
    $this->dbExecuteQuery();

    return;
    }
    // Metodo per eseguire insert o update con bind
    public function querySqlBindInsUpDel($query,$params){

    // Parsing della query SQL
    $this->dbParseQuery($query);
    // Bind delle variabili
    $this->dbBind($query,$params);
    // Esecuzione della query
    $this->dbExecuteQuery();

    return;
    }


    /*
    * Metodo per eseguire query sql
    *
    * note: questo metodo effettua la query e ritorna un array numerico monodimensionale
    * se si è selezionato un solo attributo, e un array numerico bidimensionale
    * se si è selezionato un insieme di attributi.
    */
    public function querySql($query){

    // Parsing della query SQL
    $this->dbParseQuery($query);
    // Esecuzione della query
    $this->dbExecuteQuery();
    // Costruisco l'array dei risultati in modo numerico
    $result = $this->dbNumericResult();

    // L'array (monodimensionale o multidimensionale) è caricato
    return $result;

    }

    /*
    * Metodo per eseguire query sql con ritorno di un array associativo
    *
    * note: questo metodo effettua la query e ritorna un array monodimensionale
    * numerico se si è selezionato un solo attributo, e un array
    * bidimensionale numerico/associativo se si è selezionato un insieme
    * di attributi.
    */
    public function querySqlAssoc($query){

    // Parsing della query SQL
    $this->dbParseQuery($query);
    // Esecuzione della query
    $this->dbExecuteQuery();
    // Costruisco l'array dei risultati in modo associativo
    $result = $this->dbAssociativeResult();

    // L'array (monodimensionale o multidimensionale) è caricato
    return $result;

    }

    /*
    * Metodo per eseguire query sql con bind di variabili
    *
    * note: questo metodo effettua la query e ritorna un array numerico monodimensionale
    * se si è selezionato un solo attributo, e un array numerico bidimensionale
    * se si è selezionato un insieme di attributi.
    */
    public function querySqlBind($query,$params){

    // Parsing della query SQL
    $this->dbParseQuery($query);
    // Bind delle variabili
    $this->dbBind($query,$params);
    // Esecuzione della query
    $this->dbExecuteQuery();
    // Costruisco l'array dei risultati in modo numerico
    $result = $this->dbNumericResult();

    // L'array (monodimensionale o multidimensionale) è caricato
    return $result;

    }

    /*
    * Metodo per eseguire query sql con ritorno di un array associativo e bind di variabili
    *
    * note: questo metodo effettua la query e ritorna un array monodimensionale
    * numerico se si è selezionato un solo attributo, e un array
    * bidimensionale numerico/associativo se si è selezionato un insieme
    * di attributi.
    */
    public function querySqlAssocBind($query,$params){

    // Parsing della query SQL
    $this->dbParseQuery($query);
    // Bind delle variabili
    $this->dbBind($query,$params);
    // Esecuzione della query
    $this->dbExecuteQuery();
    // Costruisco l'array dei risultati in modo numerico
    $result = $this->dbAssociativeResult();

    // L'array (monodimensionale o multidimensionale) è caricato
    return $result;

    }

    // Metodo distruttore
    public function __destruct(){
    // Chiudo
    $this->dbCloseConn();
    }

    }
    ?>


    Sono ben accetti commenti/proposte/soluzioni e qualsiasi cosa vi venga in mente!

  4. #4
    implementare le transaction nel senso che io magari vorrei fare:

    Codice PHP:

    //da qualche parte nella mia app
    $conn = new dbManager();

    ....


    //ad un certo punto apro la connessione
    $conn->open();


    ....

    //eseguo query varie
    $ret $conn->executeQuery("my sql");

    ...

    //voglio fare una transazione
    $conn->begin();

    $ret $conn->executeQuery("my sql");

    if(!
    $ret)
      
    $conn->rollback();
    else
      
    $conn->commit();

    ...


    //fine sezione con il dbManager
    $conn->close(); 
    Il fatto che con la tua classe tu non possa scegliere quando aprire e chiudere la connessione in maniera implicita, io la vedo un pò come una limitazione. Il non poter aprire/chiudere transazioni indipendentemente da eventuali procedure impostate nel db, la vedo come una limitazione. L'handler degli errori usando echo e exit, la vedo come un errore: usa throw per lanciare eccezioni catturabili con try/catch dalle classi/Script che usano questa classe. Il resto poi non l'ho guardato

    ps: usa i tag [ P H P ] e [ / P H P ] per includere codici php che altrimenti sono poco leggibli
    IP-PBX management: http://www.easypbx.it

    Old account: 2126 messages
    Oldest account: 3559 messages

  5. #5
    nn ti conviene usare PDO che ha anche un parametro per le connessioni persistenti??

  6. #6
    Originariamente inviato da fermat
    nn ti conviene usare PDO che ha anche un parametro per le connessioni persistenti??
    il driver per oracle (PDO_OCI) è settato come "sperimentale" in php.net, non mi sembra una scelta oculata usarlo.
    IP-PBX management: http://www.easypbx.it

    Old account: 2126 messages
    Oldest account: 3559 messages

  7. #7
    Originariamente inviato da Santino83_02
    il driver per oracle (PDO_OCI) è settato come "sperimentale" in php.net, non mi sembra una scelta oculata usarlo.
    ah ok nn sapevo.
    allora direi proprio di no.

  8. #8
    Scusate, avete ragione. Ma le operazioni sono corrette o manca qualche controllo? Valuterò singolarmente i vostri suggerimenti, per i quali intanto vi ringrazio.

    Codice PHP:
    <?php

    class dbManager {


        
    // Definizione degli Attributi di classe

        
    private $dbh;        // Connettore database
        
    private $dbUser;    // Utente del database
        
    private $dbPwd;        // Password utente
        
    private $dbName;    // Nome del database
        
    private $charset;    // Charset
        
    private $stat;        // Statement per l'esecuzione della query

        // Metodo costruttore
        
    public function __construct(){

            
    // Valorizzo i dati per la connessione al database (ESEMPIO)
            
    $this->dbUser 'xxxx';
            
    $this->dbPwd 'yyyy';
            
    $this->dbName 'wwww';
            
    $this->charset 'zzzz';
            
    $this->dbOpenConn();
        }

        
    /*
         * **************************************************************
         *
         *                             METODI PRIVATI
         *
         * **************************************************************
         */

        // Metodo per connettersi al database
        
    private function dbOpenConn(){
            
    $this->dbh oci_connect($this->dbUser,$this->dbPwd,$this->dbName,$this->charset);
        }

        
    // Metodo per disconnettere il database
        
    private function dbCloseConn(){
            
    oci_close($this->dbh);
        }

        
    // Metodo per fare il parsing della query
        
    private function dbParseQuery($query){
            
    $this->stat oci_parse($this->dbh,$query);
            if (!
    $this->stat){
                echo 
    oci_error($this->stat);
                exit();
            }
        }

        
    // Metodo per eseguire la query
        
    private function dbExecuteQuery(){
            if (!
    oci_execute($this->stat)){
                echo 
    oci_error($this->stat);
                exit();
            }
        }

        
    // Metodo per il bind delle variabili
        
    private function dbBind($query,$params){

            
    $nomi = array();
            
    $valori = array();

            
    // Recupero i nomi e i valori delle variabili
            
    foreach ($params as $v_name => $v_value){
                
    $nomi[] = $v_name;
                
    $valori[] = $v_value;
            }

            
    // Eseguo il bind per ogni coppia nome->valore
            
    for ($i=0;$i<count($nomi);$i++)
            
    oci_bind_by_name($this->stat,$nomi[$i],$valori[$i]);

        }

        
    /*
         * Metodo per costruire l'array dei risultati in modo numerico.
         * Se il risultato è un insieme di record, si ha una matrice avente
         * tante righe quanti sono i risultati della query (da 0 a n-1).
         * Se il risultato è un solo record invece ritorna un array con i valori
         * risultanti
         */
        
    private function dbNumericResult(){
            
    // Uso un contatore per assegnare le righe
            
    $j 0;

            
    $result = array();

            while (
    oci_fetch($this->stat)){

                
    // Ogni elemento dell'array è un array di posti pari al numero di colonne

                // Se ho una sola colonna carico l'array monodimensionale
                
    if (oci_num_fields($this->stat) == 1){
                    
    $result[] = oci_result($this->stat,1);
                }

                
    // Se ho più di una colonna, uso un array bidimensionale
                
    else{
                        
                    
    // Per ogni colonna aggiungo aggiungo il valore ritornato dalla query
                    
    for ($i=0;$i<oci_num_fields($this->stat);$i++){
                        
    $result[$j][$i] = oci_result($this->stat,$i+1);
                    }
                    
    $j++;
                }
            }

            if (
    count($result) == 1)
                return 
    $result[0];
            return 
    $result;
        }

        
    /*
         * Metodo per costruire l'array associativo dei risultati
         * Se il risultato è un insieme di record, si ha una matrice in cui ogni riga
         * è rappresentata da un numero e ogni campo dal nome dello stesso. Se invece
         * si ha un unico record, il metodo ritorna un array associativo.
         */

        
    private function dbAssociativeResult(){

            
    $result = array();

            
    // Se seleziono una sola colonna ottengo un array numerico
            
    if (oci_num_fields($this->stat) == 1)
            while (
    oci_fetch($this->stat))
            
    $result[] = oci_result($this->stat,1);
            else{
                while (
    $result[] = oci_fetch_array($this->stat,OCI_ASSOC)){}

                
    /* L'ultima assegnazione è vuota perchè la condizione non si verifica
                 * quindi tolgo l'ultimo elemento dall'array, altrimenti se ne conta
                 * uno in più
                 */
                
    unset($result[count($result)-1]);
            }

            if (
    count($result) == 1)
            return 
    $result[0];
            return 
    $result;
        }

        
    /*
         * **************************************************************
         *
         *                             METODI PUBBLICI
         *
         * **************************************************************
         */

        // Metodo per eseguire insert o update
        
    public function querySqlInsUpDel($query){

            
    // Parsing della query SQL
            
    $this->dbParseQuery($query);
            
    // Esecuzione della query
            
    $this->dbExecuteQuery();

            return;
        }
        
    // Metodo per eseguire insert o update con bind
        
    public function querySqlBindInsUpDel($query,$params){

            
    // Parsing della query SQL
            
    $this->dbParseQuery($query);
            
    // Bind delle variabili
            
    $this->dbBind($query,$params);
            
    // Esecuzione della query
            
    $this->dbExecuteQuery();

            return;
        }


        
    /*
         * Metodo per eseguire query sql
         *
         * note:     questo metodo effettua la query e ritorna un array numerico monodimensionale
         *             se si è selezionato un solo attributo, e un array numerico bidimensionale
         *             se si è selezionato un insieme di attributi.
         */
        
    public function querySql($query){

            
    // Parsing della query SQL
            
    $this->dbParseQuery($query);
            
    // Esecuzione della query
            
    $this->dbExecuteQuery();
            
    // Costruisco l'array dei risultati in modo numerico
            
    $result $this->dbNumericResult();

            
    // L'array (monodimensionale o multidimensionale) è caricato
            
    return $result;

        }

        
    /*
         * Metodo per eseguire query sql con ritorno di un array associativo
         *
         * note:     questo metodo effettua la query e ritorna un array monodimensionale
         *             numerico se si è selezionato un solo attributo, e un array
         *             bidimensionale numerico/associativo se si è selezionato un insieme
         *             di attributi.
         */
        
    public function querySqlAssoc($query){

            
    // Parsing della query SQL
            
    $this->dbParseQuery($query);
            
    // Esecuzione della query
            
    $this->dbExecuteQuery();
            
    // Costruisco l'array dei risultati in modo associativo
            
    $result $this->dbAssociativeResult();

            
    // L'array (monodimensionale o multidimensionale) è caricato
            
    return $result;

        }

        
    /*
         * Metodo per eseguire query sql con bind di variabili
         *
         * note:     questo metodo effettua la query e ritorna un array numerico monodimensionale
         *             se si è selezionato un solo attributo, e un array numerico bidimensionale
         *             se si è selezionato un insieme di attributi.
         */
        
    public function querySqlBind($query,$params){

            
    // Parsing della query SQL
            
    $this->dbParseQuery($query);
            
    // Bind delle variabili
            
    $this->dbBind($query,$params);
            
    // Esecuzione della query
            
    $this->dbExecuteQuery();
            
    // Costruisco l'array dei risultati in modo numerico
            
    $result $this->dbNumericResult();

            
    // L'array (monodimensionale o multidimensionale) è caricato
            
    return $result;

        }

        
    /*
         * Metodo per eseguire query sql con ritorno di un array associativo e bind di variabili
         *
         * note:     questo metodo effettua la query e ritorna un array monodimensionale
         *             numerico se si è selezionato un solo attributo, e un array
         *             bidimensionale numerico/associativo se si è selezionato un insieme
         *             di attributi.
         */
        
    public function querySqlAssocBind($query,$params){
                
            
    // Parsing della query SQL
            
    $this->dbParseQuery($query);
            
    // Bind delle variabili
            
    $this->dbBind($query,$params);
            
    // Esecuzione della query
            
    $this->dbExecuteQuery();
            
    // Costruisco l'array dei risultati in modo numerico
            
    $result $this->dbAssociativeResult();

            
    // L'array (monodimensionale o multidimensionale) è caricato
            
    return $result;

        }

        
    // Metodo distruttore
        
    public function __destruct(){
            
    // Chiudo
            
    $this->dbCloseConn();
        }

    }

  9. #9
    In merito alla questione delle transazioni, se come query passo una cosa del genere:

    "insert into <tabella> <ecc..> ;
    if <condizione> then
    commit;
    else
    rollback;
    end if;
    "

    non sto eseguendo perfettamente una transazione??

    Originariamente inviato da Santino83_02
    implementare le transaction nel senso che io magari vorrei fare:

    Codice PHP:

    //da qualche parte nella mia app
    $conn = new dbManager();

    ....


    //ad un certo punto apro la connessione
    $conn->open();


    ....

    //eseguo query varie
    $ret $conn->executeQuery("my sql");

    ...

    //voglio fare una transazione
    $conn->begin();

    $ret $conn->executeQuery("my sql");

    if(!
    $ret)
      
    $conn->rollback();
    else
      
    $conn->commit();

    ...


    //fine sezione con il dbManager
    $conn->close(); 
    Il fatto che con la tua classe tu non possa scegliere quando aprire e chiudere la connessione in maniera implicita, io la vedo un pò come una limitazione. Il non poter aprire/chiudere transazioni indipendentemente da eventuali procedure impostate nel db, la vedo come una limitazione. L'handler degli errori usando echo e exit, la vedo come un errore: usa throw per lanciare eccezioni catturabili con try/catch dalle classi/Script che usano questa classe. Il resto poi non l'ho guardato

    ps: usa i tag [ P H P ] e [ / P H P ] per includere codici php che altrimenti sono poco leggibli

  10. #10
    se programmi direttamente nel database si, ma quando programmi in un linguaggio esterno al database solitamente si fa, ad esempio, come ti ho detto io. Anche perchè lo scopo di fondo sarebbe gestire meno sql possibile...tu addirittura ci gestisci la transazione.

    Per quanto riguarda la tua classe, non so che dirti. Funzionerà secondo il modo che tu hai impostato di usarla (errore a parte, ma non ho un db oracle su cui fare un test), però secondo me ha una serie di problemi concettuali che in parte ho già esposto nell'esempio sopra. Poi in un contesto oop le mancanze risultano palesi e darebbero fastidio nella programmazione. In un contesto di scripting probabilmente ha anche un suo senso, anche se io metterei l'apertura della connessione "opzionabile", e la chiusura fissa nel distruttore per essere sicuri che, se aperta, la connessione venga chiusa
    IP-PBX management: http://www.easypbx.it

    Old account: 2126 messages
    Oldest account: 3559 messages

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.