- Home
- Categorie
- Coding e Sistemistica
- PHP
- [RISOLTO] PDO Singleton e type hinting
-
[RISOLTO] PDO Singleton e type hinting
Salve ho un curioso problema...in pratica non mi sta funzionando più il type hinting seppur credo di implementarlo in modo corretto.
Il problema.
Sto sviluppando un portale che necessita di accedere al database da varie classi che, per ovvie ragioni, non possono tutte essere estensioni di una sola unica classe Factory. A tal proposito ho sviluppato un semplice Singleton di prova per PDO come da scheletro proposto di seguito[php]
<?phpclass PDOFactory
{/** Propietà private per la connessione al database */ static private $_bPDOSingletonInstance; static private function getInstance() { /** Codice che verifica se self::$_bPDOSingletonInstance è settata e se non lo è crea la nuova istanza */ }
}
?>
[/php]Tale singleton lo invoco in questo modo (non uso qua un blocco try catch perchè l'ho già dentro al metodo getInstance e mi richiama, in caso di errore, un metodo statico che impagina il messaggio)
[php]
<?phprequire_once 'class.PDOFactory.php';
$objPDO = PDOFactory::getInstance();
[/php]
Fino qua tutto bene ma se voglio, ad esempio, verificare che l'istanza esiste e creo una classe di prova come la seguente
[php]
<?phpclass ProvaIstanza
{private $objPDO; public function verifica(PDO $objPDO) { if ( self::$ObjPDO) { echo "Istanza corerttamente passata"; } else { echo "Non c'è nessuna istanza"; } }
}
?>
[/php]e modifico il codice precedente in questo modo
[php]
<?php
require_once 'class.PDOFactory.php';
require_once 'class.ProvaIstanza.php';
$objPDO = PDOFactory::getInstance();
$objProvaIstanza = new ProvaIstanza($objPDO)
$objProvaIstanza->verifica();
[/php]stampa correttamente il messaggio "Istanza correttamente passata" ma ci agginge anche il seguente errore
**Catchable fatal error**: Argument 1 passed to ProvaIstanza::verifica() must be an instance of PDO, none given, called in (nome del file e riga).
Qualche idea si come risolvere il problema ?
Grazie
-
Come non detto: risolto. Se il metodo singleton è statico pure i metodi che implementano il type hinting devono esserlo.
Bastano queste due modifiche e il tutto funziona
[php]
<?phpclass ProvaIstanza
{private $objPDO; static public function verifica(PDO $objPDO) { if ( self::$ObjPDO) { echo "Istanza corerttamente passata"; } else { echo "Non c'è nessuna istanza"; } }
}
?>
[/php][php]
<?php
require_once 'class.PDOFactory.php';
require_once 'class.ProvaIstanza.php';
$objPDO = PDOFactory::getInstance();
ProvaIstanza::verifica($objPDO)
[/php]
Se a qualcuno serve qua c'è il codice completo per la verifica
index.php
[php]
<?phprequire_once 'Configuration.php';
require_once 'class.PDOFactory.php';
require_once 'class.StampaArticoli.php';$objPDO = PDOFactory::getInstance();
$objPDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
StampaArticoli::anteprima($objPDO);?>
[/php]namespace.php
[php]
<?php
namespace PDOFactory
{const PDONAME = 'mysql'; const PDOHOST = 'localhost'; const PDOPORT = 3306; const PDOCHARSET = 'utf8'; const PDOUSERNAME = 'tuoUtente'; const PDOPASSWORD = 'tuaPassword'; const PDODBNAME = 'tuoDatabase'; const PDOOPTIONS = null;
}
?>
[/php]
class.PDOFactory.php
[php]
<?phpclass PDOFactory
{static private $_sPDOName = PDOFactory\PDONAME; static private $_sPDOHost = PDOFactory\PDOHOST; static private $_iPDOPort = PDOFactory\PDOPORT; static private $_sPDOCharset = PDOFactory\PDOCHARSET; static private $_sPDOUsername = PDOFactory\PDOUSERNAME; static private $_sPDOPassword = PDOFactory\PDOPASSWORD; static private $_sPDODbName = PDOFactory\PDODBNAME; static private $_bPDOSingletonInstance; public function __construct() { } public function __clone() { } static public function getInstance() { if ( !self::$_bPDOSingletonInstance ) { try { self::$_bPDOSingletonInstance = new PDO ( self::$_sPDOName . ':host=' . self::$_sPDOHost . ';dbname=' . self::$_sPDODbName . ';charset=' . self::$_sPDOCharset . ';port=' . self::$_iPDOPort, self::$_sPDOUsername, self::$_sPDOPassword ); } catch (PDOException $e) { die ('PDOError: ' . $e->getMessage()); } } return self::$_bPDOSingletonInstance; }
}
?>
[/php]mentre la classe StampaArticoli è una semplice classe di prova con un solo metodo giusto per verificare il funzionamento del tutto; non è detto che sia la soluzione ottimale per tutti ma serve a verificare il funzionamento
[php]
<?phpclass StampaArticoli
{private $objPDO;
static public function anteprima (PDO $objPDO) { try { foreach($objPDO->query('SELECT * FROM articoli') as $row) { echo $row['testoArticolo'] . '<br />'; } } catch (PDOException $e) { die ('Error: ' . $e->getMessage()); } }
}
?>
[/php]a tutta sta pappardella stampa correttamente:
Questo è il primo articolo Questo è il secondo articolo Questo è il terzo articolo
Spero sia utile a qualcuno
Ciauz