We want to create a PHP5 OOP class which can help us connect to our MYSQL server.
We could not decide if we wanted to use the MYSQL or MYSQLI connector, so we use them both (and can select which one to use).
We should be able to have multiple connections open at the same time, using both connectors.
We should have a single class only containing the database information (hostname and such) so we can have multiple connections at ones.
We want to test the class using both connectors at the same time in the end of this tutorial.
If you are new to OOP development in PHP5, please read one of the other OOP PHP5 tutorials on this page before reading this.
First, we need to create the class that contains the configurations of our databases:
class config
{
public $hostname;
public $username;
public $password;
public $database;
public $prefix;
public $connector;
function __construct($hostname = NULL, $username = NULL, $password = NULL, $database = NULL, $prefix = NULL, $connector = NULL)
{
$this->hostname = !empty($hostname) ? $hostname : "";
$this->username = !empty($username) ? $username : "";
$this->password = !empty($password) ? $password : "";
$this->database = !empty($database) ? $database : "";
$this->prefix = !empty($prefix) ? $prefix : "";
$this->connector = !empty($connector) ? $connector : "mysqli";
}
function __destruct()
{
}
}
This class will only contain some fields we can use to store our data in and a constructor to feed the fields with data and a deconstructor to clean up the object then we decides to remove it.
The fields are:
hostname: the hostname of your database.
username: the username used to login to your database.
password: the password in clear text to login to your database.
database: the name of the database.
prefix: if you decide to use table prefixes, you should enter the prefix here as: "prefix_".
constructor: this is IMPORTANT: type mysql or mysqli here to select which database connector to use, we decide to use mysqli for you if you can't decide it.
We can use the config class as this in the examples below and in your code:
$config = new config("hostname", "username", "password", "database", "prefix", "connector");
And because of our design here, we can have multiple objects of the class config (to store information about two databases):
$config_db_1 = new config("hostname", "username", "password", "database", "table_prefix", "connector");
$config_db_2 = new config("hostname", "username", "password", "database", "table_prefix", "connector");
So now, we have stored the information of two databases, now we only need the hard part: the db class.
First we creates the class and adds some private variables to store the selected config object in.
class db
{
private $connection;
private $selectdb;
private $lastQuery;
private $config;
}
These variables should both share the login and server information, but also data such as the open connection and the last query we used (this will be used as an example later).
Now, we know that PHP5 OOP classes needs to have an constructor and deconstructor, lets add them, descriptions follow:
class db
{
private $connection;
private $selectdb;
private $lastQuery;
private $config;
function __construct($config)
{
$this->config = $config;
}
function __destruct()
{
}
}
Constructor:
This function are called every single time we create an object of the db class and takes one argument, the config class object.
If you decide not to use the argument, the variables inside will be assigned some default values, and it is here we select to use the mysqli connector as default.
Destructor:
This function does the clean up and removes everything from the object when we decide not to use it anymore (or the pages that we have build are done loading in the browser).
Before we can use the db class to anything, we need to add some functions to open and close the connections.
Function to open connection: (remember that we wanted to use two connectors here).
public function openConnection()
{
try
{
if($this->config->connector == "mysql")
{
$this->connection = mysql_connect($this->config->hostname, $this->config->username, $this->config->password);
$this->selectdb = mysql_select_db($this->config->database);
}
elseif($this->config->connector == "mysqli")
{
$this->connection = mysqli_connect($this->config->hostname, $this->config->username, $this->config->password);
$this->selectdb = mysqli_select_db($this->connection, $this->config->database);
}
}
catch(exception $e)
{
return $e;
}
}
This function first look at the selected connector and if we decided to use mysql, it will connect to the database using mysql and in the same way, it can connect to the database using mysqli, it also selects our database using the correct function (depending on if you selected mysql or mysqli as connector).
If you have a fast-moving head, you could see that we have decided to make the openConnection function PUBLIC, the reason for this is that we want to be able to use this class in many ways, we have added a little feature here, so we can use this class to hold the connection open ONES for the hole website or for every single time we want to run a query (I will add an example of what i mean).
The next function is the close connection function:
public function closeConnection()
{
try
{
if($this->config->connector == "mysql")
{
mysql_close($this->connection);
}
elseif($this->config->connector == "mysqli")
{
mysqli_close($this->connection);
}
}
catch(exception $e)
{
return $e;
}
}
Again, this function reads our config object to see which connector we are using and then closes the connection of the right connector, this function is also used public, because we want to be able to call it then needed outside the class.
Lets add the latest two functions to our db class:
class db
{
private $connection;
private $selectdb;
private $lastQuery;
private $config;
function __construct($config)
{
$this->config = $config;
}
function __destruct()
{
}
public function openConnection()
{
try
{
if($this->config->connector == "mysql")
{
$this->connection = mysql_connect($this->config->hostname, $this->config->username, $this->config->password);
$this->selectdb = mysql_select_db($this->config->database);
}
elseif($this->config->connector == "mysqli")
{
$this->connection = mysqli_connect($this->config->hostname, $this->config->username, $this->config->password);
$this->selectdb = mysqli_select_db($this->connection, $this->config->database);
}
}
catch(exception $e)
{
return $e;
}
}
public function closeConnection()
{
try
{
if($this->config->connector == "mysql")
{
mysql_close($this->connection);
}
elseif($this->config->connector == "mysqli")
{
mysqli_close($this->connection);
}
}
catch(exception $e)
{
return $e;
}
}
}
How much fun do we have now?, we can open and close a connection to a database using both mysql and mysqli connectors, but we can't use the class to anything, the feature we need is to run queries of cause.
But before we adds a function to run a query, we need to think a little, because people on websites can't be trusted, they perform SQL injections if they can, so we need to be sure of that they can't on our classes, what we need is a function to add a " / " char before every " ' " char in the queries, this will stop people from attacking our databases with crappy inputs.
The code for this are:
public function ecapeString($string)
{
if($this->config->connector == "mysql")
{
return mysql_real_escape_string($string);
}
elseif($this->config->connector == "mysqli")
{
return mysqli_real_escape_string($this->connection, $string);
}
}
Now we can start on our query function:
public function query($query)
{
}
First we have to handle the use of table prefixes:
public function query($query)
{
$query = str_replace("}", "", $query);
$query = str_replace("{", $this->config->prefix, $query);
}
If the prefix is defined, we will change the query to contain that pre-stored prefix, this means that all our table names in queries, should be written as {table}.
The next thing is a big bunch of code, but we place it under the if in the function:
public function query($query)
{
$query = str_replace("}", "", $query);
$query = str_replace("{", $this->config->prefix, $query);
try
{
if(empty($this->connection))
{
$this->openConnection();
if($this->config->connector == "mysql")
{
$this->lastQuery = mysql_query($this->ecapeString($query));
}
elseif($this->config->connector == "mysqli")
{
$this->lastQuery = mysqli_query($this->connection, $this->ecapeString($query));
}
$this->closeConnection();
return $this->lastQuery;
}
else
{
if($this->config->connector == "mysql")
{
$this->lastQuery = mysql_query($this->ecapeString($query));
}
elseif($this->config->connector == "mysqli")
{
$this->lastQuery = mysqli_query($this->connection, $this->ecapeString($query));
}
return $this->lastQuery;
}
}
catch(exception $e)
{
return $e;
}
}
First we changes the prefix as described, next we checks if the connection to the database is open, if not, we need to open it (if the connection is closed here, we know that we have selected to open and close the connection every single time we run a query, if the connection is open here, we know that we have decided to have one connection open for every browser used to access our site, and to save server resources), last we stores the results of the query in the lastQuery variable.
The last thing, we will of cause also handle the database connector here. but we did store the data in the lastQuery variable, this is because we can use this to output the last query used by the user.
Let us add a little bonus function to output the last used query to the browser ( if you need it ):
public function lastQuery()
{
return $this->lastQuery;
}
simple?.
Lets put it together as it is now:
class db
{
private $connection;
private $selectdb;
private $lastQuery;
private $config;
function __construct($config)
{
$this->config = $config;
}
function __destruct()
{
}
public function openConnection()
{
try
{
if($this->config->connector == "mysql")
{
$this->connection = mysql_connect($this->config->hostname, $this->config->username, $this->config->password);
$this->selectdb = mysql_select_db($this->config->database);
}
elseif($this->config->connector == "mysqli")
{
$this->connection = mysqli_connect($this->config->hostname, $this->config->username, $this->config->password);
$this->selectdb = mysqli_select_db($this->connection, $this->config->database);
}
}
catch(exception $e)
{
return $e;
}
}
public function closeConnection()
{
try
{
if($this->config->connector == "mysql")
{
mysql_close($this->connection);
}
elseif($this->config->connector == "mysqli")
{
mysqli_close($this->connection);
}
}
catch(exception $e)
{
return $e;
}
}
public function ecapeString($string)
{
return addslashes($string);
}
public function query($query)
{
$query = str_replace("}", "", $query);
$query = str_replace("{", $this->config->prefix, $query);
try
{
if(empty($this->connection))
{
$this->openConnection();
if($this->config->connector == "mysql")
{
$this->lastQuery = mysql_query($this->ecapeString($query));
}
elseif($this->config->connector == "mysqli")
{
$this->lastQuery = mysqli_query($this->connection, $this->ecapeString($query));
}
$this->closeConnection();
return $this->lastQuery;
}
else
{
if($this->config->connector == "mysql")
{
$this->lastQuery = mysql_query($this->ecapeString($query));
}
elseif($this->config->connector == "mysqli")
{
$this->lastQuery = mysqli_query($this->connection, $this->ecapeString($query));
}
return $this->lastQuery;
}
}
catch(exception $e)
{
return $e;
}
}
public function lastQuery()
{
return $this->lastQuery;
}
}
It could be fun to see if the connection to the database is open, let us add a function that can do that for us:
public function pingServer()
{
try
{
if($this->config->connector == "mysql")
{
if(!mysql_ping($this->connection))
{
return false;
}
else
{
return true;
}
}
elseif($this->config->connector == "mysqli")
{
if(!mysqli_ping($this->connection))
{
return false;
}
else
{
return true;
}
}
}
catch(exception $e)
{
return $e;
}
}
This function will, depending on the connector, ping the server to see if we have an active connection to it.
As of now, we can connect to a database, close the connection, ping the server and run a query, but we can't handle the returned data from the database, so we need 4 new functions to do just that:
hasRows: to see if the data we got has any rows in it.
countRows: returns the number of rows in the returned data.
Some people prefer to use the fetch_assoc functions to handle the data, others the fetch_arry, so we need to be large here and add them both:
fetchAssoc: returns all data with the mysql_fetch_assoc or mysqli_fetch_assoc functions.
fetchArray: returns add data with the mysql_fetch_array or mysqli_fetch_array functions.
The code for the functions is:
public function hasRows($result)
{
try
{
if($this->config->connector == "mysql")
{
if(mysql_num_rows($result)>0)
{
return true;
}
else
{
return false;
}
}
elseif($this->config->connector == "mysqli")
{
if(mysqli_num_rows($result)>0)
{
return true;
}
else
{
return false;
}
}
}
catch(exception $e)
{
return $e;
}
}
public function countRows($result)
{
try
{
if($this->config->connector == "mysql")
{
return mysql_num_rows($result);
}
elseif($this->config->connector == "mysqli")
{
return mysqli_num_rows($result);
}
}
catch(exception $e)
{
return $e;
}
}
public function fetchAssoc($result)
{
try
{
if($this->config->connector == "mysql")
{
return mysql_fetch_assoc($result);
}
elseif($this->config->connector == "mysqli")
{
return mysqli_fetch_assoc($result);
}
}
catch(exception $e)
{
return $e;
}
}
public function fetchArray($result)
{
try
{
if($this->config->connector == "mysql")
{
return mysql_fetch_array($result);
}
elseif($this->config->connector == "mysqli")
{
return mysqli_fetch_array($result);
}
}
catch(exception $e)
{
return $e;
}
}
These functions are the last ones to add to our class, and then we can view some examples of the use.
The complete classes:
class db
{
private $connection;
private $selectdb;
private $lastQuery;
private $config;
function __construct($config)
{
$this->config = $config;
}
function __destruct()
{
}
public function openConnection()
{
try
{
if($this->config->connector == "mysql")
{
$this->connection = mysql_connect($this->config->hostname, $this->config->username, $this->config->password);
$this->selectdb = mysql_select_db($this->config->database);
}
elseif($this->config->connector == "mysqli")
{
$this->connection = mysqli_connect($this->config->hostname, $this->config->username, $this->config->password);
$this->selectdb = mysqli_select_db($this->connection, $this->config->database);
}
}
catch(exception $e)
{
return $e;
}
}
public function closeConnection()
{
try
{
if($this->config->connector == "mysql")
{
mysql_close($this->connection);
}
elseif($this->config->connector == "mysqli")
{
mysqli_close($this->connection);
}
}
catch(exception $e)
{
return $e;
}
}
public function ecapeString($string)
{
return addslashes($string);
}
public function query($query)
{
$query = str_replace("}", "", $query);
$query = str_replace("{", $this->config->prefix, $query);
try
{
if(empty($this->connection))
{
$this->openConnection();
if($this->config->connector == "mysql")
{
$this->lastQuery = mysql_query($this->ecapeString($query));
}
elseif($this->config->connector == "mysqli")
{
$this->lastQuery = mysqli_query($this->connection, $this->ecapeString($query));
}
$this->closeConnection();
return $this->lastQuery;
}
else
{
if($this->config->connector == "mysql")
{
$this->lastQuery = mysql_query($this->ecapeString($query));
}
elseif($this->config->connector == "mysqli")
{
$this->lastQuery = mysqli_query($this->connection, $this->ecapeString($query));
}
return $this->lastQuery;
}
}
catch(exception $e)
{
return $e;
}
}
public function lastQuery()
{
return $this->lastQuery;
}
public function pingServer()
{
try
{
if($this->config->connector == "mysql")
{
if(!mysql_ping($this->connection))
{
return false;
}
else
{
return true;
}
}
elseif($this->config->connector == "mysqli")
{
if(!mysqli_ping($this->connection))
{
return false;
}
else
{
return true;
}
}
}
catch(exception $e)
{
return $e;
}
}
public function hasRows($result)
{
try
{
if($this->config->connector == "mysql")
{
if(mysql_num_rows($result)>0)
{
return true;
}
else
{
return false;
}
}
elseif($this->config->connector == "mysqli")
{
if(mysqli_num_rows($result)>0)
{
return true;
}
else
{
return false;
}
}
}
catch(exception $e)
{
return $e;
}
}
public function countRows($result)
{
try
{
if($this->config->connector == "mysql")
{
return mysql_num_rows($result);
}
elseif($this->config->connector == "mysqli")
{
return mysqli_num_rows($result);
}
}
catch(exception $e)
{
return $e;
}
}
public function fetchAssoc($result)
{
try
{
if($this->config->connector == "mysql")
{
return mysql_fetch_assoc($result);
}
elseif($this->config->connector == "mysqli")
{
return mysqli_fetch_assoc($result);
}
}
catch(exception $e)
{
return $e;
}
}
public function fetchArray($result)
{
try
{
if($this->config->connector == "mysql")
{
return mysql_fetch_array($result);
}
elseif($this->config->connector == "mysqli")
{
return mysqli_fetch_array($result);
}
}
catch(exception $e)
{
return $e;
}
}
}
class config
{
public $hostname;
public $username;
public $password;
public $database;
public $prefix;
public $connector;
function __construct($hostname = NULL, $username = NULL, $password = NULL, $database = NULL, $prefix = NULL, $connector = NULL)
{
$this->hostname = !empty($hostname) ? $hostname : "";
$this->username = !empty($username) ? $username : "";
$this->password = !empty($password) ? $password : "";
$this->database = !empty($database) ? $database : "";
$this->prefix = !empty($prefix) ? $prefix : "";
$this->connector = !empty($connector) ? $connector : "mysqli";
}
function __destruct()
{
}
}
And now to the fun part, examples:
For every example, we have placed the two classes in a file called: db.class.php
For every config object, you can use: MYSQL or MYSQLI.
1. example: a simple connection to a database, using only one connection for each browser.
<?PHP
// We start by including the classes.
include('db.class.php');
// We need to have 1 config object with all data in.
$config = new config("hostname", "username", "password", "database", "prefix", "connector"); //type in your data here…
// Now we need to have access to the db class, we uses the config object to configure the db object.
$db = new db($config);
// We can now open the connection to the database.
$db->openConnection();
// If your config details are right, we are now connected to a database, lets test the connection before we run queries.
$are_we_online = $db->pingServer();
// The variable $are_we_online should be true (or 1) if we are connected to the server.
echo "Are we online: " . $are_we_online; // prints 0 or 1.
// Let us run a query.
$sql = $db->query("SELECT * FROM {table}");
// The variable $sql will now hold the data returned from the database, we can now work with it.
// Does it have rows ?
$hasRows = $db->hasRows($sql);
echo "Does it have rows: " . $hasRows; // prints 0 or 1 (true or false).
// How many rows does it have.
$countRows = $db->countRows($sql);
echo "How many rows: " . $countRows; // returns the number of rows.
// We can get the data from the fetch_assoc function.
$result = $db->fetchAssoc($sql);
// We can get the data from the fetch_array function.
$result = $db->fetchArray($sql);
We can even print out the latest used query:
echo $db->lastQuery();
// As a last thing, close the connection.
$db->closeConnection();
?>
2. example: connection to a single database using the "one connection pr query"-method, this will slowdown your code a little and generate more resource-use on the server.
<?PHP
// We start by including the classes.
include('db.class.php');
// We need to have 1 config object with all data in.
$config = new config("hostname", "username", "password", "database", "prefix", "connector"); //type in your data here…
// Now we need to have access to the db class, we uses the config object to configure the db object.
$db = new db($config);
// We don't need to start the connection here, because we opens it every single time we runs a query.
// If your config details are right, we are now connected to a database, lets test the connection before we run queries.
$are_we_online = $db->pingServer();
// The variable $are_we_online should be true (or 1) if we are connected to the server.
echo "Are we online: " . $are_we_online; // prints 0 or 1.
// Let us run a query.
$sql = $db->query("SELECT * FROM {table}");
// The variable $sql will now hold the data returned from the database, we can now work with it.
// Does it have rows ?
$hasRows = $db->hasRows($sql);
echo "Does it have rows: " . $hasRows; // prints 0 or 1 (true or false).
// How many rows does it have.
$countRows = $db->countRows($sql);
echo "How many rows: " . $countRows; // returns the number of rows.
// We can get the data from the fetch_assoc function.
$result = $db->fetchAssoc($sql);
// We can get the data from the fetch_array function.
$result = $db->fetchArray($sql);
We can even print out the latest used query:
echo $db->lastQuery();
// We don't need to close the connection here, because we only starts it when needed.
?>
3. example: multiple connections open at ones.
<?PHP
// We start by including the classes.
include('db.class.php');
// We need to have 2 config objects with all data in.
$config1 = new config("hostname", "username", "password", "database", "prefix", "connector"); //type in your data here…
$config2 = new config("hostname", "username", "password", "database", "prefix", "connector"); //type in your data here…
// Now we need to have access to the db class, we uses the config object to configure the db object.
$db1 = new db($config1);
$db2 = new db($config2);
// We can now open the connection to the databases.
$db1->openConnection();
$db2->openConnection();
// If your config details are right, we are now connected to the databases, lets test the connection before we run queries.
$are_we_online_1 = $db1->pingServer();
$are_we_online_2 = $db2->pingServer();
// The variable $are_we_online should be true (or 1) if we are connected to the server.
echo "Are we online width 1: " . $are_we_online_1; // prints 0 or 1.
echo "Are we online width 2: " . $are_we_online_2; // prints 0 or 1.
// Let us run a query.
$sql1 = $db1->query("SELECT * FROM {table}");
$sql2 = $db2->query("SELECT * FROM {table}");
// The variable $sql will now hold the data returned from the database, we can now work with it.
// Does it have rows ?
$hasRows1 = $db1->hasRows($sql1);
$hasRows2 = $db2->hasRows($sql2);
echo "Does it have rows: " . $hasRows1; // prints 0 or 1 (true or false).
echo "Does it have rows: " . $hasRows2; // prints 0 or 1 (true or false).
// How many rows does it have.
$countRows1 = $db1->countRows($sql1);
$countRows2 = $db2->countRows($sql2);
echo "How many rows 1: " . $countRows1; // returns the number of rows.
echo "How many rows 2: " . $countRows2; // returns the number of rows.
// We can get the data from the fetch_assoc function.
$result1 = $db1->fetchAssoc($sql1);
$result2 = $db2->fetchAssoc($sql2);
// We can get the data from the fetch_array function.
$result1 = $db1->fetchArray($sql1);
$result2 = $db2->fetchArray($sql2);
We can even print out the latest used query:
echo $db1->lastQuery();
echo $db2->lastQuery();
// As a last thing, close the connection.
$db1->closeConnection();
$db2->closeConnection();
?>
4. example: using multiple connectors but only have the connection open when needed.
<?PHP
// We start by including the classes.
include('db.class.php');
// We need to have 2 config objects with all data in.
$config1 = new config("hostname", "username", "password", "database", "prefix", "connector"); //type in your data here…
$config2 = new config("hostname", "username", "password", "database", "prefix", "connector"); //type in your data here…
// Now we need to have access to the db class, we uses the config object to configure the db object.
$db1 = new db($config1);
$db2 = new db($config2);
// Because we want only to have an open connection when needed, we don't have to open it here.
// If your config details are right, we are now connected to the databases, lets test the connection before we run queries.
$are_we_online_1 = $db1->pingServer();
$are_we_online_2 = $db2->pingServer();
// The variable $are_we_online should be true (or 1) if we are connected to the server.
echo "Are we online width 1: " . $are_we_online_1; // prints 0 or 1.
echo "Are we online width 2: " . $are_we_online_2; // prints 0 or 1.
// Let us run a query.
$sql1 = $db1->query("SELECT * FROM {table}");
$sql2 = $db2->query("SELECT * FROM {table}");
// The variable $sql will now hold the data returned from the database, we can now work with it.
// Does it have rows ?
$hasRows1 = $db1->hasRows($sql1);
$hasRows2 = $db2->hasRows($sql2);
echo "Does it have rows: " . $hasRows1; // prints 0 or 1 (true or false).
echo "Does it have rows: " . $hasRows2; // prints 0 or 1 (true or false).
// How many rows does it have.
$countRows1 = $db1->countRows($sql1);
$countRows2 = $db2->countRows($sql2);
echo "How many rows 1: " . $countRows1; // returns the number of rows.
echo "How many rows 2: " . $countRows2; // returns the number of rows.
// We can get the data from the fetch_assoc function.
$result1 = $db1->fetchAssoc($sql1);
$result2 = $db2->fetchAssoc($sql2);
// We can get the data from the fetch_array function.
$result1 = $db1->fetchArray($sql1);
$result2 = $db2->fetchArray($sql2);
We can even print out the latest used query:
echo $db1->lastQuery();
echo $db2->lastQuery();
// We don't need to close anything here, because we closes the connection after every query are run.
?>
I hope that this ( little and advanced ) tutorial on a dual connector for mysql can help you in your development.
EDIT: changed the name of the __destruct() functions to be valid, changed mysqli_query to have two arguemnts, changed constructor to use the config class the right way, changed $this->connector to $this->config->connector and changed PingServer function, changed a single variable name.
This post has been edited by Kuggi: 27 March 2011 - 04:17 AM






MultiQuote







|