-
Probably the most popular pattern form PHP and not only.
Motivation:
Restriction to a single instance of a resource across the app, accessible from anywhere.
Diagram:
Implementation:
The classic example for PHP is the database resource. The database connection must be unique across the app, not to establish multiple connections to the database and as a consequence resources to be wasted.
For a single instance to exist the constructor must only be accessible from a static method, and the resulting object must not have the posibillity to be cloned. Also the class must not be extensible.
Example:
1// db connection information 2define ( 'DB_HOST', 'localhost' ); 3define ( 'DB_USER', 'user' ); 4define ( 'DB_PASS', 'pass' ); 5define ( 'DB_DATABASE', 'db' ); 6 7/** 8 * Singleton class for database connection management using mysqli 9 */ 10final class SingletonDB { 11 12 /** 13 * Singleton instance 14 * 15 * @var SingletonDB 16 */ 17 protected static $_instance = null; 18 19 /** 20 * Connection resource 21 * 22 * @var resource 23 */ 24 protected $_connection = null; 25 26 /** 27 * Constructor which also connects to the database 28 * 29 */ 30 protected function __construct() { 31 // connection to database server 32 $this->_connection = new mysqli ( DB_HOST, DB_USER, DB_PASS ); 33 34 // in case of an error connection an exception is thrown 35 if ($this->_connection->connect_error) { 36 throw new Exception ( 'Error connection to mysql server' ); 37 } 38 39 // selecting the database 40 $this->_connection->select_db ( DB_DATABASE ); 41 42 // in case of an error selecting the database an exception is thrown 43 if ($this->_connection->error) { 44 throw new Exception ( 'Error selecting database' ); 45 } 46 47 } 48 49 /** 50 * Run SQL queries 51 * 52 * @param string $query SQL query 53 * @return mysqli_result 54 */ 55 public function query($query) { 56 return $this->_connection->query ( $query ); 57 } 58 59 /** 60 * Access for error messages 61 * 62 * @return string 63 */ 64 public function error() { 65 return $this->_connection->error; 66 } 67 68 /** 69 * Method that is called when cloning an object 70 * Is protected so is not possible to clone the object 71 * 72 */ 73 protected function __clone() { 74 } 75 76 /** 77 * Close connection and destroy the object 78 * 79 */ 80 public function __destruct() { 81 $this->_connection->close (); 82 } 83 84 /** 85 * Method that returns an SingletonDB instance 86 * 87 * @return SingletonDB 88 */ 89 public static function getInstance() { 90 if (self::$_instance == null) { 91 self::$_instance = new SingletonDB ( ); 92 } 93 94 return self::$_instance; 95 } 96} 97 98try { 99 // SingletonDB instance 100 $db = SingletonDB::getInstance (); 101 102 // Query to be run 103 $q = 'SELECT * FROM test'; 104 105 // the query will return an mysqli_result object 106 $result = $db->query ( $q ); 107 108 // check for errors and display them 109 if ($db->error ()) { 110 111 echo $db->error (); 112 113 } else { 114 // extract the result and display 115 while ( $row = $result->fetch_assoc () ) { 116 var_dump ( $row ); 117 } 118 // close mysqli_result object 119 $result->close (); 120 } 121// in case of exception there is displayed 122} catch ( Exception $e ) { 123 echo $e->getMessage (); 124}