Home / Programmazione / PHP / Connessione con PDO
Mattepuffo

Connessione con PDO

Connessione con PDO

Articolo aggiornato -> Utilizzo di Singleton

Tutti quelli che cominciamo a programmare in PHP imparano a usare le varie funzioni specifiche per db; nel caso di MySQL tutte le funzioni mysql_*:

  • mysql_connect
  • mysql_select_db
  • mysql_query
  • .....

A mio modo di vedere c'è molto codice replicato tra le pagine ed intoltre se un giorno si cambiasse db si dovrebbe fare una gran faticaccia per cambiare le funzioni.

Un grosso aiuto viene da PDO.

I vantaggi di PDO sono:

  • più performante
  • più sicuro
  • più riutilizzabile

Vediamo come connetterci usando, inoltre, il PHP a oggetti piuttosto che il classico PHP procedurale.

Creiamo un nuovo file Connessione.php; qua ci sarà la classe che rappresenta il nostro db:

<?php

/**
 * @author Matteo Ferrone <matteo.ferrone@gmail.com>
 * @since 2015-05-31
 */
class Connessione {

    private $pdo;
    private static $instance;

    private function __construct() {
        try {
            $this->pdo = new PDO('mysql:host=localhost;dbname=DBNAME', 'USERNAME', 'PASSWORD', array(
                PDO::ATTR_PERSISTENT => TRUE,
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
            ));
        } catch (PDOException $e) {
            echo '<p class="error">' . $e->getMessage() . '</p>';
            die();
        }
    }

    /**
     * Get the instance of Connessione
     *
     * @return instance of Connessione
     */
    public static function getInstance() {
        if (!isset(self::$instance)) {
            $c = __CLASS__;
            self::$instance = new $c;
        }
        return self::$instance;
    }

    /**
     * Cloning is no allowed
     */
    public function __clone() {
        trigger_error('Clone is not allowed', E_USER_ERROR);
    }

    /**
     * Execute the query without prepared statement
     *
     * @param string $cmd Command
     * @param int $dieOrNot If you want that the script stop in case of error
     * @return array
     */
    public function execQuery($cmd, $dieOrNot = FALSE) {
        try {
            $result = $this->pdo->query($cmd);
            return $result;
        } catch (PDOException $e) {
            echo '<p class="error">' . $e->getMessage() . '</p>';
            if ($dieOrNot) {
                die();
            }
        }
    }

    /**
     * Execute the query with prepared statement
     *
     * @param string $cmd Command
     * @param int $dieOrNot If you want that the script stop in case of error
     * @return array
     */
    public function execQueryPrepare($cmd, $arrayCampi, $dieOrNot = FALSE) {
        try {
            $prepare = $this->pdo->prepare($cmd);
            $prepare->execute($arrayCampi);
            return $prepare->fetchAll();
        } catch (PDOException $e) {
            echo '<p class="error">' . $e->getMessage() . '</p>';
            if ($dieOrNot) {
                die();
            }
        }
    }

    /**
     * Execute the insert, update or delete with prepared statement
     *
     * @param string $cmd Command
     * @param array $arrayCampi Array of value
     * @param int $dieOrNot If you want that the script stop in case of error
     * @return void
     */
    public function execPrepare($cmd, $arrayCampi, $dieOrNot = FALSE) {
        try {
            $prepare = $this->pdo->prepare($cmd);
            $prepare->execute($arrayCampi);
        } catch (PDOException $e) {
            return '<p class="error">' . $e->getMessage() . '</p>';
            if ($dieOrNot) {
                die();
            }
        }
    }

    /**
     * Execute the insert, update or delete with prepared statement
     *
     * @param string $cmd Command
     * @param array $arrayCampi Array of value
     * @param int $dieOrNot If you want that the script stop in case of error
     * @return int Last id inserted
     */
    public function execPrepareLastId($cmd, $arrayCampi, $dieOrNot = FALSE) {
        try {
            $prepare = $this->pdo->prepare($cmd);
            $prepare->execute($arrayCampi);
            return $this->pdo->lastInsertId();
        } catch (PDOException $e) {
            return '<p class="error">' . $e->getMessage() . '</p>';
            if ($dieOrNot) {
                die();
            }
        }
    }

    /**
     * Execute the query with prepared statement, just for login
     *
     * @param string $cmd Command
     * @param array $arrayCampi Array of value
     * @return array or FALSE in case of wrong login
     */
    public function execQueryLogin($cmd, $arrayCampi) {
        try {
            $cmd = $this->pdo->prepare($cmd);
            $cmd->execute($arrayCampi);
            if ($cmd->rowCount() == 1) {
                return $cmd->fetchAll();
            } else {
                return FALSE;
            }
        } catch (PDOException $e) {
            return '<p class="error">' . $e->getMessage() . '</p>';
            die();
        }
    }

}

Nel costruttore creiamo la connessione con vari attributi; sotto prendiamo l'istanza della connessione (sto usando Singleton).

Poi ci sono vari metodi accessori che possiamo richiamare nelle nostre classi; funzioni per eseguire le varie query.

In tutte le funzioni ci sono i blocchi try/catch per gestire le eccezioni.

Vediamo un semplice esemio di query:

include_once './Connessione.php';
$connessione = Connessione::getInstance();
$select = 'SELECT utente_email, count( * ) AS cnt FROM utenti GROUP BY utente_email HAVING cnt >1 ORDER BY cnt DESC';
$res = $connessione->execQuery($select);
foreach ($res as $key => $val) {
    echo $key . '->' . $val . '<br>';
}

Qui una lista dei driver supportati da PDO.

Enjoy!