Static Connection Objects: Classes, Properties and Methods

connectReusable Connection Tools

Some years ago, Steve Krug wrote a book entitled, Don’t Make Me Think!. That sums up how I feel about MySQL connections with PHP. When I make a PHP-MySQL application, all I want to do is to call up a connection object and method, make my connection and go about using it as a mysqli object. I don’t want to have to think about it. I don’t want to have to re-write an error-handling sequence, and if I change the connection information, I want a single source where I can go and make changes without fear that the whole thing won’t blow sky-high. If you like, you can download the connection files along with a test class before continuing:
Download

The Big Boom Theory

A while back on this blog I posted a simple connection pattern. An interface stored connection information in the form of constants and an implemented class returned a connection object. The idea is to provide a simple and reusable application for MySQL connections.

In the book, I created a similar set of classes for making connections, but instead of using non-static variables I used static ones. The UniversalConnect class shows the use of static variables:

<?php
include_once('IConnectInfo.php');
class UniversalConnect implements IConnectInfo
{
	private static $server=IConnectInfo::HOST;
	private static $currentDB= IConnectInfo::DBNAME;
	private static $user= IConnectInfo::UNAME;
	private static $pass= IConnectInfo::PW;
	private static $hookup;
 
	public function doConnect()
	{
		self::$hookup=mysqli_connect(self::$server, self::$user, self::$pass, self::$currentDB);
		if(self::$hookup)
		{
			echo "Successful connection to MySQL:<br/>";
		}
		elseif (mysqli_connect_error(self::$hookup)) 
		{
    		echo('Here is why it failed: '  . mysqli_connect_error());
		}
		return self::$hookup;
	}
}
?>

To create an instance of the mysqli object in a static environment, the following line (13) is employed:

13 $this->hookup=UniversalConnect::doConnect();

The property, $this->hookup is a private one in the constructer function of the using class. In tests on two of three hosts, the results showed the following:

Successful connection to MySQL:
Old table proxyLog has been dropped.
Table proxyLog has been created successfully.

However, in the third host, using PHP 5.4, the same code generated the following error:

Strict Standards: Non-static method UniversalConnect::doConnect() should not be called statically, assuming $this from incompatible context in D:\ABC\XYZ\jblow\PHPdp\tablework\CreateTable.php on line 13 Successful connection to MySQL:
Old table proxyLog has been dropped.
Table proxyLog has been created successfully.

Testing it on a fourth server, I got the expected results. But I still could not find what the problem was.

Static for All

The problem turned out to be minor (don’t they always) and was solved simply by making the method that returns the msqli connection static. This required both the doConnect method to be declared static in the interface and in the UniversalConnect class. The following listing shows how the repair was made so that on hosting services with Strict Standards, you won’t run into problems. (It’s also a better overall practice.)

<?php
//Filename: IConnectInfo.php
//Substitute your connect info
interface IConnectInfo
{
	const HOST ="localhost";
	const UNAME ="phpDesign";
	const PW ="phpPatterns";
	const DBNAME = "phpBase";
 
	public static function doConnect();
}
?>
 
<?php
//Filename: UniversalConnect.php
//ini_set("display_errors","1");
//ERROR_REPORTING(E_ALL);
include_once('IConnectInfo.php');
 
class UniversalConnect implements IConnectInfo
{
	private static $server=IConnectInfo::HOST;
	private static $currentDB= IConnectInfo::DBNAME;
	private static $user= IConnectInfo::UNAME;
	private static $pass= IConnectInfo::PW;
	private static $hookup;
 
	public static function doConnect()
	{
		self::$hookup=mysqli_connect(self::$server, self::$user, self::$pass, self::$currentDB);
		if(self::$hookup)
		{
			echo "Successful connection to MySQL:<br/>";
		}
		elseif (mysqli_connect_error(self::$hookup)) 
		{
    		        echo('Here is why it failed: '  . mysqli_connect_error());
		}
		return self::$hookup;
	}
}
?>
 
//The following file is an example of how to use a static method
//without instantiating the class of which the method is a part
//Any file where you need a MySQL connection works the same.
<?php
//ini_set("display_errors","1");
//ERROR_REPORTING(E_ALL);
include_once('UniversalConnect.php');
class CreateTable
{
	private $tableMaster;
	private $hookup;
 
	public function __construct()
	{
		$this->tableMaster="sandTable";
 
                //Single line to create mysqli object
		$this->hookup=UniversalConnect::doConnect();
 
		$drop = "DROP TABLE IF EXISTS $this->tableMaster";
 
		if($this->hookup->query($drop) === true)
		{
			printf("Old table %s has been dropped.<br/>",$this->tableMaster);
		}
 
		$sql = "CREATE TABLE $this->tableMaster (id SERIAL, uname NVARCHAR(15), pw NVARCHAR(10), PRIMARY KEY (id))";
 
		if($this->hookup->query($sql) === true)
		{
			printf("Table $this->tableMaster has been created successfully.<br/>");
		}
		$this->hookup->close();
	}
}
$worker=new CreateTable();
?>

The first two files are the interface and implementation for the UniversalConnect object, and the third file is just a sample of what you might use it for.

Keep Host Aware

I’ve had to work with a lot of different hosting services and configurations over which I have little or no control. Currently, I regularly use five different hosts, four of which are run by sysadmins who have levels of skill varying from novice to the-best-there-is (student sysadmins often change our PHP.ini files in the learning process.) The only host I can really control all the time is my host on my LAN. I can change the php.ini file so that I have the desired level of security, standards and access. Because of these variations I often use the following two lines:

ini_set("display_errors","1");
ERROR_REPORTING(E_ALL);

In this way, I don’t have to worry about the skill level of the sysadmin (and I do have to worry!). If I find something I do or don’t like about the php.ini configuration, I can always reset them myself or ask the sysadmin at a later date to make the fix. In the meantime, though, until I’m sure about how the php.ini file is configured, I’m going to include lines that make sure I get full error reporting.

After my experience with the static properties and method, I’m changing my error reporting to:

ERROR_REPORTING( E_ALL | E_STRICT );

In working with design patterns and OOP, you need all the feedback you can get. Of course, the best plan is to set your php.ini file so you have your error reporting set the way you want, but if you don’t have full control over configurations, you need a backup plan.

Share

Copyright © 2013 William Sanders. All Rights Reserved.

6 Responses to “Static Connection Objects: Classes, Properties and Methods”


  • Thanks! Just what i was looking for…can you please give other examples that would simplify queries? -thanks.
    PS-great site; bookmarked.

  • Hi Ash501,

    Could you give me an idea of what kind of queries you’re interested in seeing.

    Thanks,
    Bill

  • Hi Bill, missed your reply…

    Was just wondering what would be an effective way to place variables for queries in OOP? just started learning OOP and classes, and wondered where to place the queries, inside, outside of the class separated in an include? since logic and design are apart was thinking that SQL should be also?

    In short, any example with a list of queries that are needed prior to a class, or functions to build a page.

    Thanks!

  • Hi Ash501,

    Take a look at Part IV of the CMS Series on this blog. You will find a private function named loadContent(). I have the listing here:

    private function loadContent()
        {
            //Create Query Statement
    	$this->sql ="SELECT * FROM $this->tableMaster WHERE id = 1";
     
    	if ($result = $this->hookup->query($this->sql))
    	{
    	    while ($row = $result->fetch_assoc()) 
    	    {
                    $this->css = $row['css'];
                    $this->title = $row['title'];
                    $this->header1 = $row['header1'];
                    $this->header2 = $row['header2'];
                    $this->body1 = $row['body1'] . "<p />";
                    $this->body2 = $row['body2'] . "<p />";
                    $this->image1 = "images/" . $row['image1'];
                    $this->image2 = "images/" . $row['image2'];
                    $this->caption1 = $row['caption1'];
                    $this->caption2 = $row['caption2'];
    	    }
                $result->close();
    	}
            $this->hookup->close(); 
        }

    The values of the array elements are moved from the elements of the query reply into private variables belonging the RetrieveBlog class. These in turn are passed to an associative array, $content, the property that had been inherited from the abstract class PageMaster.

    Let me know if that’s what you’re looking for.

    Kindest regards,
    Bill

  • Proper to inherited your class, 3 month ago i also face this pro… but i can solve it… if u r using abstract class , PHP new generated a strict standard errors, two way for solve this error, first u can use interface and implement it or second error_reporting(0); let it go bye the error!!! 😇

  • HI Balwant,

    I updated the entire set recently. See this link.

    Thanks for your comments,
    Bill

Leave a Reply