Pagina 1 di 8 1 2 3 ... ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 80

Discussione: PDO dalla A alla Z

  1. #1

    [PILLOLA] PDO dalla A alla Z

    Introduzione all' estensione PDO per PHP5.1
    andr3a 14 / 07 / 2005


    Cos'e' PDO ?
    PDO e' un' estensione in grado di pilotare database di diverso tipo tramite un' unica interfaccia ( o meglio classe ) che con gli stessi metodi opera su mysql, mysql 4.x, sqlite 2.x, sqlite 3.x , PostgreSQL, sqlserver, oracle e chi piu' ne ha piu' ne metta.
    Solitamente questo tipo di classe, che racchiude un insieme di sotto classi trasparenti per l'utente, viene definito layer di astrazione.
    Parlando di PDO parliamo di PHP 5 e parlando di PHP 5 parliamo di programmazione ad oggetti, quindi se sapete poco / niente della OOP di php vi consiglio di leggere gli articoli di http://freephp.html.it e di documentarvi un po' prima di continuare a leggere.

    Perche' PDO ?
    PDO e' utile, indispensabile, per rendere un applicativo portabile su diverse piattaforme e diversi databases .
    E' quello che mancava al php e che in tanti hanno tentato di creare, una classe per tutti i databases ... e finalmente ecco che l' evoluazione PECL e' diventata sufficientemente stabile per includere questa estensione nella futura versione del php, la 5.1 .
    E' gia' presente, ovviamente, nella attuale distribuzione della 5.1 beta 2 , presente sul sito www.php.net .

    Differenze sostanziali dal solito "_connect" e "query" ?
    Le differenze maggiori sono date dal fatto che si usano oggetti, quindi se programmavate gia' ad oggetti non ce ne sono a livello di sintassi.
    A livello concettuale invece, si utilizza un' insieme di operazioni ormai standard o comuni per molti linguaggi, in grado di preparare query, eseguire transazioni, ricevere errory di eccezione ed altro ancora.
    Una pillola interessante che puo' fornire sufficiente conoscenza dei concetti e della sintassi che andremo ad utilizzare e' quella che parla di PHP5 e dell' estensione MySQLI.
    Se l' avete gia' letta andiamo avanti, altrimenti dategli un' occhiata poiche' vengono spiegate bene i vari metodi per prendere o inserire informazioni in modo sicuro.
    Ecco il link: http://forum.html.it/forum/showthrea...hreadid=624870


    PDO dalla a alla z
    Installazione
    A differenza di quanto e' riportato sul manuale, una volta installato PHP 5.1 beta 2 o 5.1 che sia , dovrete semplicemente aggiungere alle estensioni utilizzate quelle relative al pdo ed il database che si vuole gestire.
    Non serve quindi mettere la riga seguente:
    extension=php_pdo.dll
    poiche' il file non e' nemmeno presete in questa distribuzione.
    Bastera' mettere direttamente le estensioni che ci interessano, ovvero queste:
    codice:
    extension=php_pdo_mysql.dll
    extension=php_pdo_pgsql.dll
    extension=php_pdo_sqlite.dll
    Ovviamente se volete usare altri database potete aggiungere le restanti:
    extension=php_pdo_firebird.dll
    extension=php_pdo_mssql.dll
    extension=php_pdo_oci.dll
    extension=php_pdo_oci8.dll
    extension=php_pdo_odbc.dll
    Riavviate Apache e vedete se nel phpinfo(); c'e' una o piu' parti inerenti il driver PDO e relative versioni.

    Costruttore di un oggetto PDO
    Codice PHP:
    $mypdo = new PDO$string_dsn [, $string_username [, $string_password [, $array_driver_options]]] ); 
    $string_dsn => la stringa che indica il tipo di database e l' host con o senza porta / file da utilizzare
    Alcuni esempi:
    Codice PHP:
    $string_dsn 'mysql:host=localhost;dbname=test'// mysql
    $string_dsn 'sqlite:myfile.sqlite'// sqlite 
    Tutti gli altri esempi di come impostare il dns li trovate qui: http://it2.php.net/manual/it/function.pdo-construct.php
    $string_username => l' utente con la quale volete connettervi, esempio 'root'
    $string_password => l' eventuale password di connessione al database
    $array_driver_options => Un array con coppie chiavi=>valorei specifici per la connessione di questo oggetto / database.

    Il metodo migliore per gestire una connessione al database e' il try catch, dove sul catch PDO ha la sua eccezione dedicata:
    Codice PHP:
    try {
        
    $mypdo = new PDO($dns$user$pass);
    }
    catch(
    PDOException $e) {
        echo 
    'Errore di connessione: '.$e->getMessage();

    Se non abbiamo errori la variabile $mypdo sara' da quel punto in avanti la variabile di riferimento per la gestione del database.
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  2. #2
    Metodi dell' oggetto PDO
    Breve e rapida carrellata dei metodi messi a disposizione da un' oggetto pdo, ovvero la precendete $mypdo

    beginTransaction
    Ci permette di dire al php che cio' che stiamo facendo potrebbe non andare a buon fine e che quindi vorremmo poter tornare in dietro in caso di insuccesso.
    Questo solitamente non e' possibile se non iniziamo una transazione poiche' di default le query hanno un auto commit, ovvero una volta eseguite applicano i cambiamenti alla tabella / database senza possibilita' di tornare a come era l' attimo prima.
    Quindi questa e' una vera e propria transazione , dove al suo "interno" e' possibile fare N query e riportare tutto allo stato iniziale in qualunque punto.
    La sintassi e' semplicissima:
    Codice PHP:
    $mypdo->beginTransaction(); // punto in cui volgio cominciare a fare query in modo sicuro 

    commit
    Una volta iniziata una transazione , disabilitando quindi l' auto commit, saremmo noi a decidere quando terminare le nostre query o finire di effettuare le modifiche.
    Con commit infatti si reimposta l' autocommit del database , eseguendo a tutti gli effetti tutte le query contenute tra beginTransaction e commit.
    Codice PHP:
    // inizio la transazione
    $mypdo->beginTransaction();
    // effettuo una o piu' query ..
    // applico le query e ritorno allo stato di autocommit dell' oggetto PDO
    $mypdo->commit(); 
    Unica nota importante e' stare attenti a non usare piu' di un commit poiche' questo e' valido al fine di un solo beginTransaction ed entrambe non sono annidabili.
    Esempio errato:
    Codice PHP:
    // inizio la transazione
    $mypdo->beginTransaction();
    // effettuo una o piu' query ..
    // fino qui tutto ok quindi voglio che le modifiche siano valide
    $mypdo->commit();
    // poi voglio continuare ad andare avanti con la transazione ... ( sbagliato ) 
    In questo caso bisogna far ripartire la transazione da quel momento in poi, anche subito dopo il commit.

    Altro esempio errato:
    Codice PHP:
    $mypdo->beginTransaction();
    // query ...
     // altra transazione annidata ( sbagliato )
     
    $mypdo->beginTransaction();
     
    // altre query o sotto query
     
    $mypdo->commit();
    // altre query su quelle fatte nella transazione annidata ( sbagliato ) 
    $mypdo->commit();

    Questo perche' ovviamente deve esserci un ordine logico e soprattutto di "stato" del database per effettuare dei rollBack ( vedi poi )


    exec
    Ci permette di effettuare una query immediatamente e di sapere il numero di linee modificate o cancellate da questa query.
    Ci permette anche di effettuare query all' interno di transazioni ed in questo caso non vengono effettuate fino al commit successivo.
    Se non si effettuano modifiche / eliminazioni , e' possibile comunque usare questo metodo per fare query in modo pero' poco sicuro.
    Codice PHP:
    echo $mypdo->exec('DELETE FROM mytable WHERE id > 0');
    // sara' 3 se in mytable vi erano 3 records ... 

    errorCode
    Questo metodo e' specifico per sapere il codice di errore restituito da una query.
    Codice PHP:
    $mypdo->exec('SELECT * FROM SELECT'); // errore generato appositamente
    echo $mypdo->errorCode(); 
    La stringa risultante sara' per noi poco comprensibile poiche' e' una rappresentazione alfanumerica in ASCI del codice.
    Puo' tornare utile pero' per sapere se durante l' utilizzo dell' oggetto pdo ci sono stati errori.
    Codice PHP:
    if($mypdo->errorCode() !== '' || !$mypdo->exec('SELECT * FROM SELECT'))
        echo 
    'errore'

    errorInfo
    Come errorCode e' un metodo per sapere la "situazione" del nostro oggetto PDO.
    E' decisamente piu' utile del solo errorCode poiche' il risultato non e' una stringa ma un array di 3 elementi
    Codice PHP:
    $mypdo->exec('SELECT * FROM SELECT'); // errore generato appositamente
    echo '<pre>';
    var_dump($mypdo->errorInfo()); 
    La chiave 0 conterra' lo stesso codice rilasciato dall' errorCode
    La chiave 1 conterra' il codice numerico specifico di riferimento all' errore
    La chiave 3 conterra' il nostro "mysql_error()" , ovvero la stringa che descrive l' errore generato.
    Controlli utili per questo metodo:
    Codice PHP:
    if(count($mypdo->errorInfo()) == 1// ... tutto ok
    if(count($mypdo->errorInfo()) > 1) { // ... ci sono errori
        
    $errorinfo $mypdo->errorInfo();
        echo 
    $errorinfo[2]; // stringa con l' errore


    getAttribute
    Metodo per leggere le impostazioni del nostro oggetto PDO e di come sta pilotando il nostro database.
    Esempio:
    Codice PHP:
    echo $mypdo->getAttribute(PDO_ATTR_SERVER_VERSION);
    // stampa la versione del driver che pilota il database 
    Molti i tipi di impostazioni sono descritte qui:
    http://it2.php.net/manual/it/functio...tattribute.php
    NOTA: non tutti gli attributi sono validi per tutti i database, quindi usare con cautela.


    lastInsertId
    Qualcuno ha dubbi su cosa faccia ?
    Semplicemente restituisce il row ID dell' ultimo inserimento effettuato nel database.
    Codice PHP:
    echo (string) $mypdo->lastInsertId(); 
    NOTA: non funziona con tutti allo stesso modo e non funziona, per ora, con tutti i database.
    Attualmente comunque va su MySQL come su SQLite senza problemi , si comporta in modo differente con Postgre e visto che gli altri hanno comunque funzioni analoghe penso che a breve sara' universale.


    prepare
    Il modo piu' sicuro per eseguire una query con dati "esterni" , ci permette di scrivere con disinvoltura query senza doverci preoccupare delle sql injections ( per chi non sa cosa sono, leggi l' articolo su freephp ).
    $mypdo->prepare($query[, $array]);
    $query => la nostra query sql che puo' contenere uno o piu' simboli identificativi.
    Per simbolo identificativo si intende un punto di domanda oppure un nome preceduto dai due punti ( : ) .
    Esempio query:
    'SELECT * FROM mytable WHERE id = ? OR user = ?'
    oppure
    'SELECT * FROM mytable WHERE id = :id OR user = :user' // decisamente piu' leggibile
    Vedremo negli Statements come utilizzare / popolare questo tipo di query con i nostri dati .
    $array => un' array contente le informazioni utili all' oggetto PDO per leggere / usare la query come noi desideriamo.
    Le piu' comuni sono PDO_ATTR_CURSOR , il quale ci permette di usare il secondo esempio di stringa query, e PDO_CURSOR_SCROLL che restituisce un cursore scrollabile.


    query
    Esegue una query direttamente senza preparare alcunche' e ne restituisce il risultato.
    Molto utile per query senza dati sensibili e soprattutto molto veloce in fase di utilizzo poiche' senza usare *_num_rows o *_fetch_array o simili si puo' interagire direttamente come se fosse un array di risultati con cursore interno.
    Esempio:
    Codice PHP:
    foreach($mypdo->query('SELECT id, user FROM mytable') as $row)
         echo 
    $row['id'].' - '.$row['user'].'
    '

    NOTA: come il "vecchio" *_unbuffered_query necessita che il cursore sia alla fine prima di poter essere riutilizzato.
    Teoricamente non e' cosi' per tutti i databases ma sarebbe bene usare questo metodo solo quando siamo certi che ci sara' un risultato valido da mostrare / usare / scorrere fino alla fine.


    quote
    Analogo a mysql_escape_string o mysql_real_escape_string permette di quotare in modo giusto per il tipo di database la stringa interessata.
    Ci permette quindi di usare metodi come exec o query con dati di tipo stringa sensibili.
    Esempio:
    Codice PHP:
    $mypdo->exec('INSERT INTO mytable VALUES( 1, '.$mypdo->quote('beer \\\\'n wine').')'); 
    $mypdo->quote('beer \\'n wine') = 'beer ''n wine' con apici di apertura e chiusura compresi.
    Facile ?


    rollBack
    Ricordate il metodo beginTransaction ? Ebbene con questo e' possibile far tornare il nostro database come era.
    In pratica serve a mandare a trote tutte le query fatte tra beginTransaction() e rollBack() , permettendoci di effettuare transazioni sicure e di salvaguardare i nostri dati o il nostro database da operazioni inutili o che non hanno dato il risultato sperato.
    Esempio ?
    Codice PHP:
    $mypdo->beginTransaction();
    $mypdo->exec('DROP TABLE mytable');
    $mypdo->rollBack(); // la tabella mytable rimarra' invariata :-) 

    setAttribute
    Come ogni OOP che si rispetti la dove c'e' un "get" c'e' anche un "set" , soprattutto quando si tratta di impostazioni.
    Ed ecco che con $mypdo->setAttribute(); e' possibile settare le impostazioni del nostro oggetto PDO, ad esempio specificando se l' autocommit deve essere attivo ( default ) o disattivo cosi' da poter fare rollBacks in qualunque momento.
    Esempio:
    $mypdo->setAttribute(ATTRIBUTO_PDO, $valore_generico);
    ATTRIBUTO_PDO e' un attributo dedicato pdo, alcuni sono elencati in questa pagina:
    http://it2.php.net/manual/it/functio...tattribute.php
    altri sono quelli che si possono leggere con PDO::getAttribute()
    Altro esempio:
    Codice PHP:
    $mypdo->setAttribute(PDO_ATTR_AUTOCOMMIT0);
    echo (string) 
    $mypdo->getAttribute(PDO_ATTR_AUTOCOMMIT);
    // sara' 0 quindi l' autocommit e' disabilitato 
    NOTA: come e' per il getAttribute, il setAttribute non ha valori universali, i parametri devono essere supportati dal tipo di database che stiamo utilizzando.
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  3. #3
    Oggetti restituiti da PDO
    Fino ad ora abbiamo visto come utilizzare direttamente un oggetto PDO ma non abbiamo ancra visto niente sul cosa restituiscono i metodi dell' oggetto PDO.
    Questi ulteriori oggetti / variabili restituiti da alcuni dei metodi gia' descritti si chiamano PDOStatement .

    La descrizione degli statements a differenza di quella per i metodi non seguira' l' ordine di php.net poiche' vanno chiariti gradualmente alcuni concetti.


    PDOStatement::execute
    Abbiamo visto il metodo prepare per usare query sicure ma siamo rimasti ad un punto morto ... cosa me ne faccio di prepare se poi la query non ha senso ?
    Infatti tale metodo restituisce una variabile / oggetto in grado di effettuare le modifiche necessarie per eseguire la query.
    Primo esempio:
    Codice PHP:
    // preparo la query
    $stpdo $mypdo->prepare('UPDATE mytable SET user = "pippo" WHERE id > 10');
    // eseguo la query
    $stpdo->execute(); 
    Tutto qua' .... preparo, eseguo, questa e' la situazione base con la quale interagire su un prepare ... inutile e dispendiosa contro PDO::query o PDO::exec ???
    Ovvio, se consideriamo che la query ce la siamo fatta noi a mano ... ma non sono queste le situazioni tipo dove il PDOStatement e' veramente formidabile.
    Quali allora ? Ecco solo un esempio della stessa query:
    Codice PHP:
    // preparo la query
    $stpdo $mypdo->prepare('UPDATE mytable SET user = ? WHERE id > ?');
    // non posso eseguirla poiche' ci sono 2 punti interrogativi che in SQL non avrebbero significato ...
    // come fare ? ... ecco un metodo:
    $stpdo->execute(array('pippo'10)); 
    execute puo' ricevere come parametro un array contenente le informazioni da sostituire ai punti di domanda.
    Quando utilizziamo i punti di domanda l' ordine con cui inviare i parametri ad execute e' fondamentale ed e' esattamente da sinistra a destra.
    Una cosa da notare e' la mancanza di ->quote o di escaping della stringa pippo ... non serve ? esatto, non serve poiche' se ne occupa la classe.
    Questa sapra' che al primo punto di domanda della query ci deve essere esattamente la stringa contenuta nel primo parametro dell' array passato quindi anche se questo dovesse contenere chissacosa, non sara' possibile tentare sql injections piu' comuni perche' il valore verra' trattato esattamente come stringa tra apici e non come testo su una query.
    Idem per il secondo punto di domanda,ovvio che se al posto di un intero passiamo una stringa la query non andra' a buon fine ma comunque non ci saranno risultati inaspettati.
    Bellino eh ? ... e c'e' un altro modo gia' accennato molto piu' leggibile che ci permette di personalizzare ulteriormente la fase di preparazione query e quella di esecuzione.
    Esempio piu' leggibile:
    Codice PHP:
    // preparo la query
    $stpdo $mypdo->prepare('UPDATE mytable SET user = :user WHERE id > :id');
    // non posso passare in execute un array a chiavi numeriche
    // perche' il PDO non saprebbe cosa farsene o meglio on troverebbe riscontri
    // nella query ... quindi ? facciamo cosi'
    $stpdo->execute(array(':user'=>'pippo'':id'=>10));
    // oppure, visto che e' indifferente a questo punto l 'ordine ..
    $stpdo->execute(array(':id'=>10':user'=>'pluto')); 
    Diciamo che l' utilita' dello Statement e' gia' strabiliante ? ... boh, io lo dico
    Ma cosa fa oltre a questo execute ? Piu' che altro c'e' da chiedersi cosa fa il prepare , perche' la vera chicca sta' nel fatto che una volta preparata una struttura di una query e' possibile fare tanti execute quanti sono quelli che ci servono.
    L' esempio mostrato precedentemente ad esempio funziona alla perfezione e il risultato sara' quello del secondo execute, visto che e' un update.
    Ma se avessimo bisogno di tanti insert, di diverse select o di altre query dove la sintassi e' identica ma i valori cambiano ( id, nomi, quello che vi pare ) sara' possibile evitare di rifare il prepare ed utilizzare quello gia' dichiarato in fase di assegnazione / creazione dello Statement.
    Codice PHP:
    $stpdo $mypdo->prepare('UPDATE mytable SET user = :user WHERE id > :id');
    $stpdo->execute(array(':user'=>'pippo'':id'=>1));
    $stpdo->execute(array(':user'=>'pluto'':id'=>5));
    $stpdo->execute(array(':user'=>'paperino'':id'=>10));
    $stpdo->execute(array(':user'=>'topolino'':id'=>15));
    $stpdo->execute(array(':user'=>'cip'':id'=>20));
    $stpdo->execute(array(':user'=>'ciop'':id'=>25));
    $stpdo->execute(array(':user'=>'ziopaperone'':id'=>30)); 
    // ... e cosi' via ...
    Inoltre le prestazioni sono veramente elevate perche' viene sfruttato un sistema interno di caching da parte del prepare.
    A questo statement aggiungo solo che torna un valore di tipo booleano che ci permette di sapere se la query e' stata eseguita con successo oppure no.
    if( $stpdo->execute() ) // ... OK, query eseguita con successo


    PDOStatement::bindParam
    Se con execute possiamo lavorare tranquilli in inserimento dati, con bindParam possiamo anche stare tranquilli sul tipo di dato utilizzato in input o output durante le stored procedures.
    Sintassi:
    bool PDOStatement::bindParam ( mixed parameter, mixed &variable [, int data_type [, int length]] )
    Cominciamo con i primi 2 ...
    mixed parameter e' un numero intero se utilizziamo il punto interrogativo, altrimenti una stringa se utilizziamo il metodo piu' leggibile.
    mixed &variable e' una variabile passata per riferimento con il contenuto che deve sostituire il valore descritto nel primo parametro.
    Esempio:
    Codice PHP:
    // assegno la variabile da usare  
    $user 'pippo';

    // preparo la query
    $stpdo $mypdo->prepare('UPDATE mytable SET user = ? WHERE id > 1');
    // assegno il valore per il punto interrogativo
    $stpdo->bindParam(1$user);
    // eseguo la query
    $stpdo->execute();

    // ... oppure ...

    $stpdo $mypdo->prepare('UPDATE mytable SET user = :user WHERE id > 1');
    $stpdo->bindParam(':user'$user);
    $stpdo->execute(); 
    Fin qui' potrebbe risultare piu' comodo utilizzare l' array da inviare all' execute poiche' non ci sono differenze sostanziali per sicurezza o prestazioni se non per tempo e codice 'sprecato' per scrivere tutti questi bind.
    Infatti per i soli input e' consigliato nel sito stesso di php.net di utilizzare execute e l' array per l' execute.
    Cerchiamo di capire meglio dov'e' che bindParam fa la differenza ... e cominciamo con il terzo parametro opzionale, il data_type.
    Questo specifica il tipo di dato in input o output all' interno della stored procedures e puo' essere piu' di uno grazie all' operatore di bitwise | .
    In caso di parametro da usare in output e' necessario specificare il quarto parametro ovvero la length.
    Per approfondimenti o esempi andate in questa pagina:
    http://it2.php.net/manual/it/functio...-bindparam.php


    PDOStatement::bindColumn
    Metodo per Statement molto interessante, analogo al forse piu' conosciuto bindResult , quello usato ad esempio per MySQLI in PHP >= 5.
    In pratica si tratta di specificare prima come devono chiamarsi i dati letti da una query e di che tipo devono essere.
    Sintassi:
    bool PDOStatement::bindColumn ( mixed column, mixed &param [, int type [, int maxlen [, mixed driver_options]]] )
    mixed column e' il numero della colonna restituita dalla query mentre mixed &param e' la variabile contenente il valore restituito.
    Il primo e piu' semplice esempio che mi viene in mente e' il seguente:
    Codice PHP:
    // preparo la query
    $stpdo $mypdo->prepare('SHOW TABLES');
    // preparo il risultato
    $stpdo->bindColumn(1$table_name);
    // eseguo la query
    $stpdo->execute();
    // eseguo il loop sul risultato per avere tutti i nomi delle tabelle
    while($row $stpdo->fetch(PDO_FETCH_BOUND))
        echo 
    $table_name.'
    '
    // stampo i nomi 
    Cosa c'e' di anomalo ? Una valanga di cose ... innanzitutto la variabile $table_name era inesistente e cio' nonostante non ho avuto alcun notice o warning poiche' questa viene popolata e inizializzata ( se inesistente ) automaticamente all' interno della chiamata a bindColumn ... cosa infattibile normalmente con php.
    Poi , oltre a questo , la variabile viene automaticamente riassegnata ad ogni ciclo del while , permettendoci di evitare i soliti $row[N] per il fetch_row o $row['key'] per il fetch_assoc.
    Divertente ? Penso proprio di si, soprattutto comodo e molto piu' leggibile.
    Codice PHP:
    $stpdo $mypdo->prepare('SELECT id, user FROM mytable');
    $stpdo->bindColumn(1$idPDO_PARAM_INT);
    $stpdo->bindColumn(2$userPDO_PARAM_STR);
    $stpdo->execute();
    while(
    $row $stpdo->fetch(PDO_FETCH_BOUND))
        echo 
    "{$id} => {$user}
    "

    Ecco che subentrano il terzo e quarto parametro opzionale per questo metodo di statement, il tipo di dato e la lunghezza massima.
    Sinceramente dai tests effettuati non sembrano cambiare di molto il risultato ... anzi , sembrano non influenzarlo affatto nel senso che non esiste un casting del tipo di dato.
    Probabilmente sono utili al fine di eseguire una query ottimizzata, dove lo scripter dice a priori il tipo di dato da cercare per quel campo e il sistema interno si "organizza" per fare quel tipo di query.
    Beh, lascio a voi i tests del caso, ma se dovessero essere piu' performanti specificando il tipo di dato, sarebbe bene usarlo sempre
    L' ultimo parametro, il driver_options, e' quasi una conseguenza logica del fatto che PDO e' ancora giovane e che non si vuole lasciare niente di trascurato.
    Non c'e' alcuna docuentazione per ora in merito a questo parametro ma quasi sicuramente servira' in futuro per effettuare operazioni dedicate durante la query a seconda del database utilizzato.


    PDOStatement::fetch
    Abbiamo usato il "solito while" , seppur auiutati dalla procedura bindColumn ... ma come possiamo predere i valori in modo rapido / semplice ?
    Grazie al fetch , metodo implementato nello statement in grado di spostare il cursore dei risultati di una query in un ciclo, proprio come un while.
    Esempio:
    Codice PHP:
    // stessa procedura di prima ...
    while($stpdo->fetch(PDO_FETCH_BOUND))
        echo 
    "{$id} => {$user}
    "

    Stesso risultato, infatti il "$row =" in questo caso non serve proprio perche' usiamo il parametro PDO_FETCH_BOUND che si basa sui vari bindColumn precedentemente dichiarati.
    Ma non e' detto che ogni volta si debba usare il comodo bindColumn, no ?
    E infatti il row potrebbe esserci utile con altri parametri da specificare nel fetch, ovvero:

    PDO_FETCH_ASSOC #usatelo come mysql_fetch_assoc
    PDO_FETCH_BOTH #usatelo come mysql fetch_array, risultato duplicato, quello di default
    PDO_FETCH_BOUND #usatelo come da esempio per il bindColumn
    PDO_FETCH_LAZY #combina *_BOTH e *_OBJ , l' ammazza prestazioni , imho ...
    PDO_FETCH_OBJ #ritorna un oggetto con le proprieta' che hanno il nome dei campi, interessante
    PDO_FETCH_NUM #il mio preferito ovviamente .... analogo a mysql_fetch_row

    Alcuni esempi basati sulla query precedente:
    Codice PHP:
    // *_NUM
    while($row $stpdo->fetch(PDO_FETCH_NUM))
            echo 
    "{$row['0']} => {$row['1']}
    "
    ;

    // *_ASSOC
    while($row $stpdo->fetch(PDO_FETCH_ASSOC))
            echo 
    "{$row['id']} => {$row['user']}
    "
    ;

    // *_OBJ
    while($row $stpdo->fetch(PDO_FETCH_OBJ))
            echo 
    "{$row->id} => {$row->user}
    "
    // : sbav : 
    Per ora abbiamo visto il solo primo parametro ma ce ne sono altri, in effetti mi sono dimenticato la sintassi ...
    mixed PDOStatement::fetch ( [int fetch_style [, int cursor_orientation [, int cursor_offset]]] )
    int fetch_style e' quanto abbiamo visto fino ad ora mentre int cursor_orientation e' una costante di tipo PDO_FETCH_ORI_* riferita al tipo di cursore da utilizzare, solitamente e' NEXT quello di default, ovvero man mano che si legge il risultato questo scorre al record successivo se presente.
    L? ultimo e' l' offset, ma va ? .... e cos'e' ??? ... boh ... testato ma senza successo ... spiacenti, questo offset non funziona con mysql, perlomeno per ora.


    PDOStatement::fetchAll
    Identico al fetch per certi versi, piu' comodo per altri ma meno configurabile.
    array PDOStatement::fetchAll ( [int fetch_style] )
    Come e' facile intuire con questo metodo si evita ogni loop su query ( per crearne uno su array, meglio o peggio ??? ... dipende da quanti dati vengono restituiti e quante operazioni dobbiamo fare per questi valori restituiti o con questi ) .
    Non perdo tempo per dire che il fetch_style e' ovviamente identico a quello di fetch ( l' ho perso ... !!! ) e passo subito agli esempi:
    Codice PHP:
    $row $stpdo->fetchAll(PDO_FETCH_OBJ);
    echo 
    '<pre>';
    var_dump($row); 
    ... un array di oggetti ... bello no ? idem con ASSOC, BOTH, NUM e gli altri, solo che non sono oggetti ( ma dai ? )
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  4. #4
    PDOStatement::setFetchMode
    Setta il tipo di fetch da utilizzare di default con , appunto, fetch.
    bool PDOStatement::setFetchMode ( int mode )
    int mode e' una variabile del tipo gia' visto per i metodi di fetch, il risultato e' true se l' operazione e' avvenuta con successo, false in caso di insuccesso.
    NOTA: non setta il default di fetchAll , il quale sara' comunque, di default, *_BOTH
    Esempio:
    Codice PHP:
    $stpdo $mypdo->prepare('SELECT id, user FROM mytable');
    $stpdo->setFetchMode(PDO_FETCH_NUM);
    $stpdo->execute();
    while(
    $row $stpdo->fetch())
        echo 
    "{$row[0]} => {$row[1]}
    "



    PDOStatement::fetchSingle
    Ai ai ai ... questa proprio non mi funziona con MySQL ... ma e' la tipica funzione per stampare , riga per riga, il primo risultato di una colonna.
    Esempio:
    Codice PHP:
    // eseguo una query del tipo
    // SELECT id, user FROm mytable
    $stpdo->execute();
    echo 
    $stpdo->fetchSingle(); // sara' il solo id per la prima riga trovata
    echo $stpdo->fetchSingle(); // sara' il solo id per la seconda riga trovata
    // e cosi' via ... 


    PDOStatement::rowCount
    int PDOStatement::rowCount ( void )
    Restituisce semplicemente il numero di righe affette dall' ultima query di tipo INSERT, DELETE o UPDATE.
    Codice PHP:
    // eseguo una query del tipo
    // UPDATE mytable SET user = 'pippo' WHERE id > 3
    $stpdo->execute();
    echo (string) 
    $stpdo->rowCount(); 

    PDOStatement::columnCount
    Restituisce il numero di colonne presenti nel risultato della query.
    int PDOStatement::columnCount ( void )

    Esempio:
    Codice PHP:
    $stpdo $mypdo->prepare('SELECT id, user FROM mytable');
    $stpdo->execute();
    echo (string) 
    $stpdo->columnCount(); // 2, poiche' tornano id e user 


    PDOStatement::errorCode , PDOStatement::errorInfo
    si comportano allo stesso modo dei metodi per l' oggetto PDO.
    Esempio di applicazione:
    Codice PHP:
    if($stpdo->execute())
        
    var_dump($stpdo->fetchAll());
    else
        echo 
    'Errore: '.$stpdo->errorCode(); 
    Oppure sull' else ... $error = $stpdo->errorInfo(); echo $error[2]; // il piu' utile


    PDOStatement::getAttribute , PDOStatement::setAttribute
    Si comportano come i metodi per PDO .


    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  5. #5

  6. #6
    Moderatore di Server Apache L'avatar di marketto
    Registrato dal
    Sep 2001
    Messaggi
    5,858
    complimenti per l'ottimo lavoro
    think simple think ringo

  7. #7
    grazie marketto .... bubu mi fai un favore ?

    questo pezzo:

    PDO_FETCH_ASSOC #usatelo come mysql_fetch_assoc
    PDO_FETCH_BOTH #usatelo come mysql fetch_array, risultato duplicato, quello di default
    PDO_FETCH_BOUND #usatelo come da esempio per il bindColumn
    PDO_FETCH_LAZY #combina *_BOTH e *_OBJ , l' ammazza prestazioni , imho ...
    PDO_FETCH_OBJ #ritorna un oggetto con le proprieta' che hanno il nome dei campi, interessante
    PDO_FETCH_NUM #il mio preferito ovviamente .... analogo a mysql_fetch_row


    levalo dal tag CODE che fa un casino ... e non e' bello
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  8. #8
    bubu ?

    gm o chris, se poteste levare quel pezzo dal tag code mi fareste un favore, grazie


    P.S. sempre bubu
    hai messo questa pillola sotto PHP 5 ma in realta' e' 5.1 ( anche se il PDO puo' essere installato in versioni precedenti ).

    Quindi o metti PHP 5.1 oppure li sotto ci schiaffi anche l' altra che ho scritto per MySQLI e PHP 5 , o no ?

    boh,fai tu, grazie
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  9. #9
    Originariamente inviato da andr3a
    bubu ?

    gm o chris, se poteste levare quel pezzo dal tag code mi fareste un favore, grazie
    Fatto, vedi se va bene andrè
    Addio Aldo, amico mio... [03/12/70 - 16/08/03]

  10. #10
    Originariamente inviato da gm
    Fatto, vedi se va bene andrè
    grazie, perfetto ... adesso se mi date momentaneamente i privilegi di moderatore oltre a bannare tutti metto a posto un altro paio di cosette

    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

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.