* Private constructor to prevent it being created directly * @access private */ private function __construct { } /** * singleton method used to access the object * @access public
Trang 1* Private constructor to prevent it being created directly
* @access private
*/
private function construct()
{
}
/**
* singleton method used to access the object
* @access public
* @return
*/
public static function singleton()
{
if( !isset( self::$instance ) )
{
$obj = CLASS ;
self::$instance = new $obj;
}
return self::$instance;
}
/**
* prevent cloning of the object:
* issues an E_USER_ERROR if this is attempted
*/
public function clone()
{
trigger_error( 'Cloning the registry is not permitted',
E_USER_ERROR );
}
The constructor method (which is used to create an instance of this class as an object)
is set to private, which means we cannot call it from outside of the class This is
important as it restricts how the object is instantiated, and allows us to control how
many copies of it are created.
We next have a singleton method; this is used to access the registry If there is no
instance of the object already, then it creates a new instance and stores it within the
$instance variable If the instance variable is already set, then the object (itself)
is returned.
Trang 2Finally, to prevent the object being cloned, we have a trigger_error call, so
should we ever add a functionality that clones our registry, we will find that
an E_USER_ERROR error is produced.
Registry objects
As discussed earlier, the registry on its own is very straightforward, the more
complicated aspects are the objects that the registry will actually store and
manage access to These objects include:
Database handler
User authentication
Template management
E-mail sending
Let's look at creating those objects now.
Database
Our database object needs to have functionality for:
Connecting to the database
Managing multiple database connections
Performing queries
Returning common query information such as number of rows affected, the
last insert ID, and so on
Caching queries, particularly so we can integrate a result set with the views
(through the template handler), and pass it a cache reference, so it can
generate the results into the view
Making common queries easier (for example, inserts, updates, and deletes)
by having the queries pre-formatted within certain methods of the object
There is obviously a lot more a database object could do; we will discuss that in
a moment.
Our database object
This database class abstracts the MySQL functions from the rest of the framework
into a single file, which manages the database connection:
<?php
/**
* Database management / access class: basic abstraction
•
•
•
•
•
•
•
•
•
•
Trang 3*
* @author Michael Peacock
* @version 1.0
*/
class mysqldatabase {
/**
* Allows multiple database connections
* each connection is stored as an element in the array,
* and the active connection is maintained in a variable (see below)
*/
private $connections = array();
/**
* Tells the DB object which connection to use
* setActiveConnection($id) allows us to change this
*/
private $activeConnection = 0;
/**
* Queries which have been executed and the results cached for
* later, primarily for use within the template engine
*/
private $queryCache = array();
/**
* Data which has been prepared and then cached for later usage,
* primarily within the template engine
*/
private $dataCache = array();
/**
* Number of queries made during execution process
*/
private $queryCounter = 0;
/**
* Record of the last query
*/
private $last;
/**
* Construct our database object
*/
public function construct() { }
Trang 4Let's look through what it does, method by method:
newConnection: This method creates a new connection to a database This
is separate from the constructor for two reasons: firstly, if it were in the
constructor, we would need to pass the connection details to it, which would
mean it would need to be created separately from the other objects within the
registry Secondly, this method allows us to maintain several connections to
databases within the same object.
/**
* Create a new database connection
* @param String database hostname
* @param String database username
* @param String database password
* @param String database we are using
* @return int the id of the new connection
*/
public function newConnection( $host, $user, $password,
$database )
{
$this->connections[] = new mysqli( $host, $user,
$password, $database );
$connection_id = count( $this->connections )-1;
if( mysqli_connect_errno() )
{
trigger_error('Error connecting to host '
$this->connections[$connection_id]->error,
E_USER_ERROR);
}
return $connection_id;
}
closeConnection: This method closes the active connection (while there are
multiple connections within the object, the current object being used is stored
as a variable to keep track of it).
/**
* Close the active connection
* @return void
*/
public function closeConnection()
{
$this->connections[$this->activeConnection]->close();
}
•
•
Trang 5setActiveConnection: This method allows us to toggle which database
connection is the active one to be used.
/**
* Change which database connection is actively used for the
* next operation
* @param int the new connection id
* @return void
*/
public function setActiveConnection( int $new )
{
$this->activeConnection = $new;
}
cacheQuery: This method allows us to store a query to be processed later,
primarily to be replaced in a loop into the view.
/**
* Store a query in the query cache for processing later
* @param String the query string
* @return the pointed to the query in the cache
*/
public function cacheQuery( $queryStr )
{
if( !$result = $this->connections
[$this->activeConnection]->query( $queryStr ) )
{
trigger_error('Error executing and caching query: '
.$this->connections[$this->activeConnection]
->error, E_USER_ERROR);
return -1;
}
else
{
$this->queryCache[] = $result;
return count($this->queryCache)-1;
}
}
numRowsFromCache: This method tells us the number of rows a cached query
contains.
/**
* Get the number of rows from the cache
* @param int the query cache pointer
•
•
•