Non instanzia la classe singleton

MarcoGrazia

Utente Attivo
15 Dic 2009
852
20
28
62
Udine
www.stilisticamente.com
Sto tentando di instanziare un Singleton per aprire la connessione ad un database, ma il file chiamante mi da questo errore:
Codice:
Fatal error: Call to private db::__construct() from invalid context in C:\WLMP\HTDOCS\CMS\index.php on line 56
Alla riga 56 c'è la chiamata alla classe $dbHandle = new db(); la classe è chiamata tramite __autoload() e funziona, infatti la trova.
Ho aperto la classe senza che il database fosse presente sul server e mi aspettavo un errore in tal senso, ma non è così.
Infatti l'errore avviene prima che io chiami la funzione che di fatto tenta di aprire il database.
La classe db è questa:
Codice:
        interface idb {
		public static function connetti();
	}	//	idb
	
	class db implements idb {
		
		private static $instance = null;
		
		private function __construct() {}
		
		private function __clone() {
			throw new Exception('Cannot duplicate a singleton.');
		}	//	__clone()
		
		private function db() {
		$dsn = 'mysql:host=localhost;dbname=cms';
		$user = 'xxxx';
		$password = 'xxxxx';
		
			try {
				$dbh = new PDO($dsn, $user, $password);
				return $dbh;
			} catch (PDOException $e) {
				echo 'Connection failed: ' . $e->getMessage();
				return false;
			}
		}	//	db()
		
		public static function connetti() {
			if (!isset(self::$instance)) {
				self::$instance = new db();
			}
		return self::$instance;
		}	//	connetti()
	
	}	//	fine classe db
 
Da quello che ho capito non gli piace che un metodo dichiaratamente pubblico come __constuct()possa essere dichiarato come metodo privato.
L'assurdo a questo punto è che tutti gli esempi, persino nella documentazione ufficiale del PHP presentano quel metodo per evitare la creazione di oggetti derivati dalla funzione.
Non so che fare a parte togliere quella dichiarazione, cosa che non mi va di fare.
Forse dichiarare final la classe?
 
Ultima modifica:
Ciao Marco, penso (forse mi sbaglio) che l'errore possa essere non nella classe stessa ma nell'istanziazione della classe. In quanto singleton, quindi costruttore d'obbligo private non puoi fare :
PHP:
$dbHandle = new db();
ma per ottenere l'istanza é corretto in questo modo:
PHP:
$dbHandle = db::connetti();
...
$dbHandle->db();
....
Infatti è il metodo statico connetti che crea l' istanza
 
Hai ragione tu!
E infatti non avevo affatto notato la sottigliezza nell'esempio nella stessa documentazione online del PHP
PHP:
<?php
// This would fail because the constructor is private
$test = new Example;

// This will always retrieve a single instance of the class
$test = Example::singleton();
$test->bark();

// This will issue an E_USER_ERROR.
$test_clone = clone $test;

?>
Dov'è scritto chiaramente: This would fail because the constructor is private... santa pazienza del sintax error :D

Ok! risolto, avanti col prossimo test :ilpirata:
 

Discussioni simili