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

    [PILLOLA] Introduzione all' estensione MySQLI per PHP5 e MySQL 4.1+

    Introduzione all' estensione MySQLI per PHP5 e MySQL 4.1+
    andr3a 26 / 03 / 2004
    Basato sulla prima parte di un approfondimento del sito zend.


    Cos'e' mysqli ?
    L' estensione mysqli, introdotta nella versione 4.1.2 di PHP, ci permette di interfacciarci con le versioni piu' aggiornate del database MySQL , ovvero dalla versione 3.22, fino alla 5.

    Per avere maggiori informazioni su come installare questa features in ambiente *nix vi rimando a questa pagina, mentre per windows posso dirvi di aggiungere al PHP.INI , tra le varie estensioni, la voce extension=php_mysqli.dll e di copiare il file libmysqli.dll nella system32 [ o system, nel caso mancasse la prima ] del vostro window$.

    Perche' mysqli ?
    Perche' come cresce MySQL, cresce PHP e l 'esigenza di utilizzare le nuove features della nostra accoppiata piu' diffusa, con la possibilita' di essere utilizzata in modo OOP, decisamente piu' consono per un utilizzo in PHP5, comincia a farsi sentire e in modo abbastanza consistente.
    I vantaggi sono diversi, tra cui :
    • un ' interfaccia procedurale molto simile a quella di mysql
    • un' interfaccia OOP molto piu' semplice da estendere ed implementare
    • supporto al protocollo binario di MySQL introdotto dalla versione 4.1 ( molto piu' efficiente del precedente )
    • supporto a tutte le funzioni della libreria client MySQL C compresa la possibilita' di impostare in modo avanzato la connesssione tramite i parametri passati a mysqli_init()
    • fino a 40 volte piu' veloce rispetto la solita libreria mysql
    • piu' sicura contro attacchi esterni
    [ informazioni prese da questa pagina di riferimento ]

    Procedurale o OOP ?
    Visto l'estrema somiglianza in versione procedurale con la sintassi mysql, la mia scelta e' quella di mostrarvi come utilizzare questa estensione in modo OOP , anche perche' penso che da PHP5 in poi sia quasi un "obbligo" cominciare ad affrontare i nostri script in questo modo.
    Se volete comunque farvi un' idea delle funzioni procedurali supportate, eccovi il link alla lista di questa estensione: http://www.zend.com/manual/ref.mysqli.php#AEN68433 .


    Alcuni esempi pratici
    Connessione al database
    Vediamo subito come connetterci al database desiderato.
    [ la sola connessione verra' affrontata sia in modo procedurale che OOP ]
    Codice PHP:
    <?php
    // creo il mio oggetto connessione
    $connect mysqli_connect$host$user$password );

    // verifico che non ci siano stati problemi
    // [ in modo volutamente eccessivo ]
    if( !$connect || mysqli_connect_errno() == true ) {
        die( 
    "Errore durante la connessione: ".mysqli_connect_error() );
    }
    else {
        
    $connect->select_db$database );
    }
    ?>
    Diciamo che fino ad ora dovrebbe sembrarci tutto familiare, ovvero ci connettiamo con gli stessi parametri di una connessione mysql e poi verifichiamo l' avvenuta connessione.
    In caso di errore, verificato con il booleano ritornato dall' eventuale mancata connessione e dalla funzione mysqli_connect_errno() , che restituisce il numero dell' errore provocato, stampiamo non il simile mysqli_error() ma il dedicato mysqli_connect_error(), mentre se l' operazione di connessione e' andata a buon fine, ci selezioniamo il database con la solita procedura.

    Piu' codice ? Troppi passaggi ??? .... era meglio prima ?
    Direi di no, sia perche' ho fatto un esempio che affrontasse un po' i vari aspetti ed i vari controlli di connessione, separando la ricerca dell' errore, il check e la selezione del database, sia perche' non abbiamo ancora visto la possibilita' di selezionarci direttamente il database in connessione ( direi la via piu' semplice quando abbiamo a che fare con query su un un solo database ).
    Vediamo quindi come renderci facile , comprensibile e veloce la nostra connessione.
    Codice PHP:
    <?php
    $connect 
    mysqli_connect$host$user$password$database ) or die( mysqli_connect_error() );
    ?>
    A questo punto siamo pronti per le nostre operazioni anche se non abbiamo ancora visto come connetterci in un modo piu' OOP.
    Codice PHP:
    <?php
    $connect 
    = @new mysqli$host$user$password$database );
    if( 
    mysqli_connect_errno() ) {
        die( 
    mysqli_connect_error() );
    }
    ?>
    Ora sta a voi scegliere , se non altro per la sola connessione, quale metodo vi e' piu' familiare e/o comodo.
    [ per concludere con la connessione posso dirvi che in alternativa a mysqli_connect c'e' mysqli_real_connect ]


    La query
    La semplice query non avra' nulla di insolito , sara' solo assegnata come metodo della connessione e "fetchata" con lo stesso stile, ma riferita al suo risultato.... piu' facile a vedersi che a farsi:
    Codice PHP:
    <?php
    // connessione
    $connect mysqli_connect$host$user$password$database ) or die( mysqli_connect_error() );

    // assegnazione del risultato della query a $result
    $result $connect->query'show tables' ) or die( $connect->error );

    // controllo che ci sia almeno 1 record da mostrare ed eseguo il while per il fetch_assoc
    while( $result->num_rows && $row $result->fetch_assoc() ) {
        foreach( 
    $row as $value ) {
            echo 
    $value."
    "
    ;
        }
    }

    // chiudo la connessione
    $connect->close();
    ?>
    Direi che senza soffermarci troppo possiamo passare ad una delle parti piu' interessanti di questa estensione...


    Prepared Statements [ dichiarazioni preassegnate ??? ]
    [ scusate ma non ho idea di come italianizzare questa possibilita' ]

    Una delle novita' rispetto la versione per PHP4 di questa estensione e' quella di poter creare query piu' sicure e piu' performanti, implementando una gestione ben diversa da quella solitamente utilizzata fino ad ora.
    Questa peculiarita' si suddivide in 2 tipi di dichiarazioni preassegnate, per parametri e per risultati.

    Bound Parameters
    Questa caratteristica ci permette di assegnare dei timplates alle nostre query, cosi' da immagazzinarle all' interno del database MySQL ed eseguirle passando solo le parti , da noi definite, che andranno a sostituire le parti mancanti della nostra queery.
    Il percorso e' questo:
    PHP invia il timplate di query al database, il quale ne verifica la correttezza , la parsa e se la memorizza in uno speciale buffer. Il server MySQL ritornera' il modo per utilizzare poi questa risorsa memorizza ed eseguire la query ricostruendo il timplate gia' riconosciuto.
    Questo permette di eseguire lo stesso tipo di query, ad esempio una serie di insert o di select una sola volta, invece di dover riconvalidare ogni volta tutta la struttura della query passata.
    Oltre all' aumento di prestazioni considerevoli, questo metodo ci permette allo stesso tempo di proteggerci dalle sqlinjections, rendendo vano l 'utilizzo di funzioni tipo mysql_real_escape_string(), il che significa ulteriore performance ed ulteriore sicurezza.
    Un esempio di timplates per un INSERT potrebbe essere questo:
    codice:
    INSERT INTO City (ID, Name) VALUES (?, ?)
    Quindi diciamo al nostro serevr MySQL di prepararsi a ricevere una query dove le uniche cose da cambiare e validare saranno proprio quei 2 punti interrogativi.
    Codice PHP:
    <?php
    // mi connetto
    $connect mysqli_connect$host$user$password$database ) or die( mysqli_connect_error() );

    // invio il timplate e creo l'oggetto di riferimento
    $stmt $connect->prepare("INSERT INTO City (ID, Name, People) VALUES (?, ?, ?)");
    // preparo il tipo di dati da inviare
    $stmt->bind_param'ssi'$id$value$people );

    // metto id vuoto perche' in questo caso supponiamo sia auto_increment
    $id '';
    // scrivo il nome della citta'
    $value 'Ancona';
    // e il totale abitanti
    $people 100000;

    // eseguo
    $stmt->execute();
    // chiudo la memoria occupata per questo timplate
    $stmt->close();

    // chiudo la connessione al db
    $connect->close();
    ?>
    Nella speranza che cio' che e' stato fatto sia chiaro, vorrei soffermarmi un secondo sul metodo bind_param()
    Come avrete notato il primo campo e' una stringa, in questo caso 'ssi' e non fa parte del timplate che abbiamo inviato. A cosa serve, dunque ?
    Serve a dire a MySQL quale tipo di dati debba accettare per inserire nel timplate la parte mancante prima di eseguire la nostra query.
    Questi dati possono essere di tipo:
    codice:
    i	tutti i tipi di numeri INTERI
    d	i numeri di tipo DOUBLE o FLOAT
    b	dati di tipo BLOBs ( binario )
    s	tutti gli altri tipi di dato ( stringa, altro )
    Passiamo ora all' altra possibilita' offertaci da MySQLI.


    Bound Results
    I vantaggi in result della tecnologia finora utilizzata sono questi:
    • si crea una query che viene preparata nel server MySQL
    • si assegnano le variabili che dovranno ricevere le informazioni
      [ pre-preparate anch'esse dal server ]
    • si esegue la query
    • mentre leggiamo la linea viene chiesto a MySQL di preparare la linea successiva

    Ecco un esempio commentato.
    Codice PHP:
    <?php
    // mi connetto
    $connect mysqli_connect$host$user$password$database ) or die( mysqli_connect_error() );

    // invio il timplate e creo l'oggetto di riferimento
    if( $stmt $connect->prepare("select Name, People from City") ) {
        
        
    // specifico le variabili da ricevere
        
    $stmt->bind_result($name$people);
        
        
    // eseguo
        
    $stmt->execute();
        
        
    // ciclo line per linea
        
    while ($stmt->fetch()) {
            echo 
    "CITTA: {$name}
    ABITANTI: 
    {$people}<hr />";
        }
        
    // chiudo la memoria occupata per questo timplate
        
    $stmt->close();
    }

    // chiudo la connessione al db
    $connect->close();
    ?>
    Il fatto di "preannunciare" la query e le variabili risultanti in questo caso, secondo me ( non ho fatto prove incrociate con un mysqli_fetch_assoc ), non e' chissa quanto performante, ma anche fosse di un solo decimo di millesimo piu' veloce, non vedo perche' non utilizzarlo comunque.
    Ma quello che e' a questo punto scontato, e' l'interazione di questi 2 metodi in una sola query.
    Codice PHP:
    <?php
    // mi connetto
    $connect mysqli_connect$host$user$password$database ) or die( mysqli_connect_error() );

    // invio il timplate e creo l'oggetto di riferimento
    if( $stmt $connect->prepare("select Name, People from City where Nmae like ?") ) {

        
    // specifico la variabile per il timplate
        
    $stmt->bind_param("s"$namelike);
        
    $namelike "A%";
        
        
    // specifico le variabili da ricevere
        
    $stmt->bind_result($name$people);
        
        
    // eseguo
        
    $stmt->execute();
        
        
    // ciclo line per linea
        
    while ($stmt->fetch()) {
            echo 
    "CITTA: {$name}
    ABITANTI: 
    {$people}<hr />";
        }

        
    // chiudo la memoria occupata per questo timplate
        
    $stmt->close();
    }

    // chiudo la connessione al db
    $connect->close();
    ?>
    Credo sia opinione comune il fatto che questo modo di effettuare query sia abbastanza rivoluzionario, rispetto il metodo classico utilizzato fino ad ora, sia per struttura che per controllo.

    Velocita' di esecuzione, maggiore sicurezza, maggior controllo , non so cosa ne pensiate voi, ma io ho gia' trovato il modo di interagire con MySQL > 4.1 tramite PHP5 ed e' senza ombra di dubio questo.
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  2. #2
    Titolo modificato e pillola aggiunta :metallica
    Addio Aldo, amico mio... [03/12/70 - 16/08/03]

  3. #3
    il mio 499° post è per......


    farti i complimenti :metallica
    There are 10 types of people in the world: Those who understand binary, and those who don't.

  4. #4
    antré...sbavvosa

    solo che non so, ad es, quanto sia utilizzabile il bind dei risultati...mentre quello delle opzioni si...quello è moooolto interessante

  5. #5
    Originariamente inviato da daniele_dll
    antré...sbavvosa

    solo che non so, ad es, quanto sia utilizzabile il bind dei risultati...mentre quello delle opzioni si...quello è moooolto interessante
    il bind dei soli risultati infatti e' un po' eccessivo anche per me, pero' accoppiandolo al bind per il timplate puo' essere molto utile.
    Immagina di organizzarti in una parte di script tutte le query di cui hai bisogno, insert o select, e di passare solo quelle tipo

    codice:
    prepare( $Select_nome_citta_Require_id )
    
    bind_param( 'i', $id );
    $id = 19;
    
    bind_result( $nome, $citta );
    e via tutto lo script in questo modo, io lo trovo sicuramente "macchinoso" all' inizio, rispetto l 'approccio di select classico, ma estremamente sicuro e comodo a lungo andare.

    Per di piu' non hai il problema di dover ogni volta rispecificare i campi della tabella che ti interessano, ti arrivano gia' pronti in 2 variabili ... insomma, e' un po' particolare come approccio ma puo' portare i suoi vantaggi, imho.
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  6. #6
    comodissimo sicuramente...anche xche stavo provando 1 sistema di astrazione dell'sql ... di cui ne avevamo parlato con gianko tempo fa

    l'unico problema e che a me arrivano N variabili...e nn so il tipo

    certo...mi basterebbe fare un get_type accoppiato ad uno switch ma nn è una cosa pulitissima ^^

  7. #7
    Originariamente inviato da daniele_dll
    comodissimo sicuramente...anche xche stavo provando 1 sistema di astrazione dell'sql ... di cui ne avevamo parlato con gianko tempo fa

    l'unico problema e che a me arrivano N variabili...e nn so il tipo

    certo...mi basterebbe fare un get_type accoppiato ad uno switch ma nn è una cosa pulitissima ^^
    no no .. aspe' ... in SELECT non devi specificare il tipo di variabili , devi specificare, se vuoi, solo il WHERE campo LIKE ? ... e' quel ? che devi specificare, non i dati in estrazione dal database.

    In pratica il tutto e' per filtrare la chiamata, l' estrazione poi lavora semplicemente in un altro modo che pero' puo' interagire con il primo, quindi non devi assolutamente sapere cosa ti restituira' la select, perche' la variabile in bind_result conterra' esattamente il dato di quel campo, qualunque esso sia.

    O non ho capito cosa haio detto ??? :master:
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  8. #8
    Originariamente inviato da andr3a
    no no .. aspe' ... in SELECT non devi specificare il tipo di variabili , devi specificare, se vuoi, solo il WHERE campo LIKE ? ... e' quel ? che devi specificare, non i dati in estrazione dal database.

    In pratica il tutto e' per filtrare la chiamata, l' estrazione poi lavora semplicemente in un altro modo che pero' puo' interagire con il primo, quindi non devi assolutamente sapere cosa ti restituira' la select, perche' la variabile in bind_result conterra' esattamente il dato di quel campo, qualunque esso sia.

    O non ho capito cosa haio detto ??? :master:
    mmm io parlavo in generale riguardo ai tipi
    che poi sia sia insert o update...e in select nn c'è ne bisogno...il meccanismo rimane sempre uguale

  9. #9
    Utente di HTML.it L'avatar di pixer
    Registrato dal
    Oct 2000
    Messaggi
    614
    mi hai rubato l'idea



    ma i complimenti li meriti lo stesso, bravo sborò :metallica
    MySQL Worker - The OpenSource Multiplatform MySQL database Administrator (C++ powered)
    .:[ It resumes the development !! ]:.


  10. #10
    bella pillola, anche se la vedo solo ora.

    peccato che abbia finito proprio in questi giorni una classe d'interfaccia db che compila le query con un sistema di vsprintf() + altra roba...


    userò il mio sistema con php4 (dato che è + veloce della creazione di query tramite concatenamento stringhe), mentre mi darò al mysqli con php5.


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 © 2024 vBulletin Solutions, Inc. All rights reserved.