OOP Static call

Is it ok to do this?


class Two {

 function anything() {
   classOne::anyMethod();
 }

}

I’m sure it is but this doesn’t pose very well for if I wanted to swop out one class for another. I’d then have to make changes to the code (unless I were sure all classes were named the same).

What I want it for (and this may be another issue), is this:

I may need to create more than one database instance:


//Database exends mysqli
$db[1] = new Database(2);//database 2 used this time
$db[2] = new Database(5);//db5

I then always use Database::closeAll() at any point in my script to ensure all connections are closed. Of course $this->close wouldn’t close all instances/connections, just the one I was working on.

I know I don;t have to close all connections, but I may as well, and there are other occasions where the first part of this question applies, so please don’t just respond “no need to close”.

Database::closeAll() is this:


	public static function closeAll() {
	
		//closes ALL active instances (not just this one)
	
		global $db;
		
		foreach($db as $v) {
		
			$db[$v]->close(); unset($db[$v]);
		
		}
        }

Dunno … seems somehow lame.
Especially the part where you use global variables.

I would try to (actually i have ) implement a class which works like this :



$db1 = array(
	'user'	=> 'user',
	'pass'	=> 'pass',
	'db'	=> 'somedb_1'
);
Connection::add( $db1, 'main' );

$db2 = array(
	'user'	=> 'user',
	'pass'	=> 'pass',
	'db'	=> 'foobar-2441',
	'type'	=> 'sqlite'
);
Connection::add( $db2, 'local' );

/* later in the code */

$db = Connection::attach( 'local' );
// if connection exists then use it , if not - connect to database


/* and there in somewhere else */

Connection::close_all();

And i would go with PDO instead of mysqli.

I think I’d go with Dependency Injection and/or a ServiceLocator.
Create a “general database management” class of which you pass around a single instance.
An easy example:

class Database {
     private $_connections = array();
     public function addConnection($name, mysqli $connection) {
          $this->_connections[(string)$name] = $connection;
     }
     public function getConnection($name) {
          return array_key_exists($name, $this->_connections) ? $this->_connections[$name] : NULL;
     }
     public function closeAll() {
          foreach($this->_connections as $name => $connection) {
               $this->_connection[$name]->close();
               unset($this->_connection[$name]);
          }
     }
}

If you abstract the connection also, you’ll be able to easily replace mysqli by any other class that implements the interface.

btw, all your connections are closed at the end of the script… so unless you want to do something special there, there’s no need for this.

If you do want to do it, i would do it like this:


class Database {

# Holds all your opened connections.
private static $_connections = array();

# What connection id we have (from that upper array)
private $_connectionId = null;

# Constructor
public function __construct($id) {
  # Do your magic
  $_connectionId = array_push(self::$_connections, $this) - 1;
}

# Close all opened connections
public static function closeAll() {
foreach (self::$_connections as $connection) {
  if ($connection != null) {
  $connection->close();
  }
}
}

# Close the connection for this object
public function close() {
  # Do the magic
  self::$_connections[$_connectionId] = null;
}
}

Usage:


$db1 = new Database(1);
$db2 = new Database(2);
$db3 = new Database(3);
Database::closeAll();