PHP Class Origins: An OOP Job for the HTML UI

couchPotatoPutting HTML to Work

At some point in OOP development with PHP, I quit putting little PHP code snippets in HTML. I either left all PHP out of HTML or encapsulated HTML in a PHP heredoc string inside a class. In that way, all PHP would be part of an OOP order without any loose ends. That may seem overly fussy, but it avoids the slippery slope of degenerating back into sequential programming——patchwork quilt programming.

However, such a practice should not disallow HTML from helping out in an OOP project. A lot of times, I found myself sifting through class and method options using more conditional statements than I wanted in the Client. I realized that I could just pass the class name directly to the Client from a superglobal with origins in an HTML input form. Likewise, I could do the same for methods, and this has become a useful standard operating procedure.

To better illustrate using the HTML UI in launching a selected class object, the following application uses the color and number input elements with both class and method information stored in HTML element values. Both are trivial, but help illustrate the point: (Use Firefox, Chrome or Opera–neither Safari nor Internet Explorer implemented the HTML5 standard color input element.)
PlayDownload

It’s odd in a way that PHP developers (myself included) are so used to using HTML UIs for data input into MySql databases or making other choices, but few use the UI for calling classes and methods. However, it’s both easy and practical.

Where to Put the OOP in HTML?

You can place class and method names as values anywhere in form inputs that you’d put any data passed to PHP as superglobals. One input form I found useful is the hidden one. It’s out of the way, and you can build forms around the class with other superglobal inputs as methods. Using radio button inputs is another nice option because you can use them either for calling classes or methods with the mutual exclusivity assurance of knowing that not more than one will be called from a given group. To get started, take a look at the HTML:

< !DOCTYPE html>
<html>
<head>
    <link type="text/css" rel="stylesheet" href="tech.css"/>
    <title>Unsetting Superglobals with Classes and Methods</title>
</head>
 
<body>
    <h3>Classes and Methods</h3>
<form name="alpha" action="Client.php" method="post" target="feedback">
    Choose color from the color window:<br />
    <input type="hidden" name="class" value="ColorClass"/>
    <input type="hidden" name="method" value="doColor"/><br />
    <input type="color" name="colorNow" value="#cc0000"/>
    <p>
    <input type="submit" value="Get Color"/>
    </p> 
</form>
<form name="beta" action="Client.php" method="post" target="feedback">
    Divide or modulo the following two numbers:<br />
    <input type="hidden" name="class" value="MathClass"/>
    First:&nbsp;<input type="number" name="first" value=2/>&nbsp;
    &nbsp;Second:&nbsp;<input type="number" name="second" value=7/>
 
    <br /><input type="radio" name="method" value="doDivide"/>
    &nbsp;Divide the second by the first<br />
    <input type="radio" name="method" value="doModulo" checked=true/>
    &nbsp;Modulo the second by the first<br />
    <p>
    <input type="submit" value="Do Math"/>
    </p> 
</form>
<iframe name="feedback">feedback</iframe>
</body>
</html>

The code has two forms, alpha and beta, and you can think of them as I/O for two different classes. The feedback is returned to the iframe named feedback. Both forms have the action calls to Client.php. So the general plan is:

Client → Class->method()

In the alpha form, the class is ColorClass and the method is doColor()—both in hidden input elements. The name for the class element is “class” and the name for the method element is “method.” All the user does is to choose a color that is passed through the superglobal associated with the color input element.

In the beta form, the class is MathClass placed in a hidden input element. The user chooses either a division or modulo operation from the two radio input elements where the names of the appropriate methods are stored. Once again, the name for the class element is “class” and with mutually exclusive choices the radio button elements for selecting the method, the name is “method.” In this way, whatever superglobal named “class” will fire the correct class and call the correct method with the superglobal named “method.”

The Client

As usual, the Client is the launching pad for the operations. If your application uses different client classes depending on user choices, it’s an easy matter to have unique client names for different forms. In this particular case, the Client class doesn’t care about the form of origin for the request. It just takes the class superglobal and method superglobal names and generates a call to the appropriate class and method.

As an aside, the Client in OOP should not be as rare as some perceive it to be. In one way or another, users (or non-human request mechanisms) employ some way to request that the software do something. The Client, as a participant in a structure, is in virtually every design pattern in one way or another. Even when the Client is not directly or implicitly in a design pattern, The Gang of Four reference it as related to one of the participants in the pattern. So while this example does not use a design pattern, the Client works perfectly well in any OOP program.

< ?php
/*
 * Set up error reporting and
 * class auto-loading
*/
error_reporting(E_ALL | E_STRICT);
ini_set("display_errors", 1);
// Autoload given function name.
function includeAll($className)
{
    include_once($className . '.php');
}
//Register
spl_autoload_register('includeAll');
 
//Class definition
class Client
{
    private static $object, $method;
    //client request
    public static function request()
    {  
        self::doSuper();
        $operation = new self::$object();
        echo $operation->{self::$method}();
    }
 
    private static function doSuper()
    {
        self::$object = $_POST['class'];
        self::$method=$_POST['method'];
        unset($_POST['class']);
        unset($_POST['method']);
    }
}
Client::request();
?>

The Client file first takes care of error reporting and automatically calling classes. One experienced developer told me that adding an error-reporting function was unnecessary because it could be automatically turned on in the php.ini file. That’s true, but since I work with many different PHP environments where I have no control over the php.ini file, I’ve found it to be a good practice. You only have to put it in once place, and it takes care of error reporting for the entire program. Besides, I found that one safeguard against easy hacking is to turn off error reporting so that hackers cannot see the names of the classes involved in the application. For this blog, though, I leave the error reporting on because there’s nothing on this blog I want to hide. (Change the init_set from “1” to “0” to turn off all error-reporting.)

No Returns from Constructor Functions

The first incarnation of this application used the same two forms, but the alpha form only had the class name with the results planned to be sent back for output using a return statement. I kept getting errors, and then I learned that constructor functions (those using the __construct() method) have no returns. All they do is to instantiate the class. If you do not use the __construct() method, there’s an invisible automatic constructor function that does that for your as soon as you call new ClassName().
Continue reading ‘PHP Class Origins: An OOP Job for the HTML UI’

Share

PHP Observer Design Pattern: The SplObserver

splObserverThe Standard PHP Library

For those of you in the Boston PHP 200 Days of Coding Advanced group and for those of you who develop with design patterns, you may have noticed that I have not taken advantage of PHP’s Standard Library (SPL). In part that’s because I don’t think about it, and the other is that often I have other features for the interface I’d like to add that are not in the SPL version. Further, there are only a couple, the Iterator that Larry talks about in his book, and the Observer pattern that I’m going to discuss in this post and on April 22 at Microsoft’s NERD Center next to the MIT campus.

In an earlier post on the Observer design pattern I noted that in a future post, I’d take a look at the built-in SplObserver and SplSubject interfaces. So as promised, here it is.

The class diagram is slightly different than the original, and to indicate the built-in interfaces, the backgrounds are filled with a light tint indicating, there’s nothing for you to add. If you compare Figure 1 with the class diagram in the other Observer pattern post, you can see certain fundamental differences:

Figure 1: Observer Class diagram with SPL Interfaces

Figure 1: Observer Class diagram with SPL Interfaces

With no abstract classes as part of the interface, everything passed to the concrete Subject and Observer is going to have to be implemented. With the Subject, that means implementing the notify() method and not having some protected properties, but otherwise, there’s not a lot of differences in the structure of the SplObserver and the Observer (from scratch.)

One Message: Lots of Ways to Configure the Message

Some developers treat the Observer design pattern like a magazine subscription—one magazine; lots of subscribers. I suppose that’s a legitimate use of the Observer, but it’s very expensive. Each concrete observer must be instantiated as a unique object. While the Subject (or SplSubject) supplies the data; the observers generally create something with that data; not just look at it. So, I decided to make a simple translation simulator. A club (like any of the many PHP groups in the world) has announcements, but rather than using the Observer for sending out notifications to subscribers, I created Observers who translated the event message from English to their own language. The concrete observers are named for their languages. But to get going, play the example and download the PHP code:
PlayDownload

When you test play the app, you’ll see that the all of the checkboxes on the left are checked and the text box is filled in with an event. Likewise, the data and day inputs are set to April and 22. You can just click the “Send Announcement” button to see the results. If you change the event to something other than “200 Days of Code” the only change you’ll see is in the English version. The other ones are only a simulation of a translation except for the month—they are actually translated. The idea would be to use a translation Web service to do the actual translations.

Beginning with the implementation of the SplSubject (ClubEvents), you can see the three abstract methods have been implemented using the signature from the SplMethod interface. (Their abstract form is shown at the top as comments.)

< ?php
class ClubEvents implements SplSubject
{
    /*Built-in abstract methods
     *abstract public void attach ( SplObserver $observer )
     *abstract public void detach ( SplObserver $observer )
     *abstract public void notify ( void )
    */
    private $member;
    private $observerSet = array();
    private $content= array();
 
    //add observer
    public function attach(SplObserver $observer)
    {
        array_push($this->observerSet, $observer);
    }
 
    //remove observer
    public function detach(SplObserver $observer)
    { 
      foreach($this->observerSet as $keyNow => $valNow)
      {
        if ($valNow == $observer)
        { 
          unset($this->observerSet[$keyNow]);
        }
      }   
    }
 
    //Set event name, month and day
    public function setState(array $content)
    {
        $this->content = $content;
        $this->notify();
    }
 
    public function getState()
    {
        return $this->content;
    }
 
    //Notify "subscribers"
    public function notify()
    {
        foreach ($this->observerSet as $value)
        {
            $value->update($this);
        }
    }
}
?>

If you’re familiar with the first example of the Observer on this blog, you’ll see similarities in the concrete Subject. About the only significant difference is the fact that the notify() method is wholly implemented in the concrete class (ClubEvents) instead of the Subject abstract class. The information (or data) generated by the SplSubject comes from the Client and triggers the notify() methods by calling setState() method. So instead of looking at the Observers next, we’ll look at the Client.

The Client’s Unlikely Role

Note: A primary principle of design patterns is,

Program to the interfaces; not the implementations.

In discussing the single SplSubject implementation (ClubEvents) and the many SplObserver implementations, I’ll be referring to them by the interface name except in certain specific cases. However, the references are to any implementation of either since we must assume (correctly) that any implementation contains a certain set of methods established in the abstract parent classes built into the Standard PHP Library (SPL).
Continue reading ‘PHP Observer Design Pattern: The SplObserver’

Share

PHP Template Method Pattern: Geolocation Encapsulated

bostonI was invited to speak at on April 22 at Microsoft’s NERD Center in Boston for Month 4 of Boston PHP’s 200 Days of Code. The Advanced track of 200 Days of Coding is going through Larry Ullman’s book, PHP Advanced & OO Programming (3rd ed), and I’ll be talking about materials from Chapters 8-10. However, with a little over an hour, I am using Occam’s razor to keep things focused, pertinent and related to the relevant chapters. Chapter 10 is about Networking with PHP, and by way of preview, I thought I’d take the material that Larry has on geolocation, and put it into an OOP structure using the Template Method design pattern. I also made a number of other modifications for which Larry cannot be blamed! Go ahead and Play the program to see what it does and Download the code. (The text window defaults to sandlight.com but you can add any URL you want.)
PlayDownload

The Magical Template Method

The first thing I did was to set up the geolocation app with a Template Method. You can see previous discussions and examples of the Template Method on this blog, but I wanted to include the class diagram the Gang of Four used to see how simple but elegant this pattern actually is. Figure 1 shows this subtle but powerful method:

Figure 1: Template Method class diagram

Figure 1: Template Method class diagram

The nice thing about this design pattern is that it has lots of uses as you may have already seen on this blog. However, the same simple principle is used: Abstract methods from an abstract class are implemented in a concrete method from the same abstract class. What the Template Method does is to provide a blueprint for the order of the methods to be used with the exact content dependent on the intended use.

So, starting with the abstract class, you can see how this implementation works:

< ?php
abstract class ILocatorTemplate
{
    protected $url, $info, $data, $ip, $loc;
    protected $package=array();
    protected abstract function getLocation();
    protected abstract function bundle();
 
    //The Template Method
    protected function templateMethod()
    {
        $this->getLocation();
        $this->bundle();
    }
}
?>

A number of protected properties are first declared, including an array object, $package. Next the two primitive operations are declared, getLocation() and bundle(). The former is for getting the geolocation of a URL and the second for placing that information into the $package object. That’s it! All that’s left to do is to implement the abstract class.

The Locator class

The concrete implementation of the ILocatorTemplate adds content to the properties and concrete operations to the two abstract methods.

< ?php 
class Locator extends ILocatorTemplate
{
    public function doLocate($place)
    {
        $this->loc = $place;
        $this->templateMethod();
        return $this->package;
    }
 
    protected function getLocation()
    { 
        $this->ip = gethostbyname($this->loc);
        $this->url = 'http://freegeoip.net/csv/' . $this->ip;
 
        $this->info = fopen($this->url, 'r');
        $this->data = fgetcsv($this->info);
        fclose($this->info);
    }
 
    protected function bundle()
    {
        $this->package['IP']=$this->data[0];
        $this->package['CountryID']=$this->data[1];
        $this->package['Country']=$this->data[2];
        $this->package['StateID']=$this->data[3];
        $this->package['State']=$this->data[4];
        $this->package['City']=$this->data[5];
        $this->package['Zip']=$this->data[6];
        $this->package['latitude']=$this->data[7];
        $this->package['longitude']=$this->data[8];
    }
}
?>

The doLocate() method holds the URL passed by the user. That is placed into one of the properties declared in the abstract class, $loc. Next, the $templateMethod() fires and it, in turn, launches first the getLocation() method and then the bundle() method. It doesn’t matter what is in those methods because they were defined abstractly. Therefore, any abstract method defined as part of template method will launch regardless of its implementation, as long as it adheres to the signature form in the abstract class. The getLocation() method pretty much follows the steps Larry lays out in Chapter 10. It uses the freegeoip.net Web service which returns CSV data with the location information.

The bundle() method transfers the data from the $data array send by the Web service into an associative array, $package. The keys in the associative array will serve as labels for the data once processed in the Client class.

The last step in the process is to return the $package containing an associative array with descriptive keys and location information. That’s it….but there is one more thing before we turn to the UI and client.

The Hollywood Principle

The Template Method exemplifies a larger design pattern principle called the Hollywood Principle, simply stated,

Don’t call us. We’ll call you.

It refers to how a parent class (ILocatorTemplate) call the operations of a subclass (Locator) and not the other way around. The templateMethod() function is a concrete method from the parent class, and both the getLocation() and bundle() methods are implementations of the child class, Locator. So, the parent class method calls the child class implementations; not vice versa. This fundamental principle will help keep your PHP OOP from getting tangled up.
Continue reading ‘PHP Template Method Pattern: Geolocation Encapsulated’

Share

PHP Observer Design Pattern: The Basics

observeThe Observer design pattern is one of those patterns that is easy to understand in terms of practical utility, and it’s pretty easy to implement. The idea behind the Observer pattern is to have one main object with other objects depending on the main one to notify them when changes occur. For PHP, the Observer utility is so fundamental, there’s a built-in SplObserver interface. (Using the SplObserver along with the SplSubject will be covered in a future post.)

For example, suppose you have a data source such as an inventory saved in a MySql database. You check on the database periodically to see when you need to purchase more inventory of different products. To make it practical, you want a graph that you can tell at a glance what items need replacement and which ones don’t. However, you also want a table to give you a precise breakdown of the exact numbers in inventory. This example may sound familiar because it’s similar to the one that the Gang of Four use in Design Patterns: Elements of Reusable Object-Oriented Software in illustrating the Observer pattern. What a lot of people don’t realize is that they use the same example at the beginning of their book (page 5) to examine the Model View Controller (MVC). For those of you still using the MVC, the data is supplied by the model, and the views are the displays in different formats (a table, a bar chart, and a pie chart). To get started Play the two examples and Download the source code:
Play
playMul
Download

The Observer Class Diagram

The Observer’s class diagram is a bit perplexing. Take a look at Figure 1, and you’ll see why:

Figure 1: Observer Class Diagram

Figure 1: Observer Class Diagram

The diagram itself is pretty simple, two interfaces (Subject and Observer) and two concrete implementations (ConcreteSubject and ConcreteObserver). What’s a little confusing is the Subject interface: all three methods indicate a concrete implementation because they are not italicized. Italicized method and class (interface) names indicate abstract classes and methods or interfaces. In PHP, the SplSubject is an interface (all methods are abstract), but the diagram clearly shows some concrete implementation in the notify() method—including the pseudo code for it. Neither the attach() nor the detach() are italicized, but the book (p. 295) indicates that the Subject provide attach/detach interfaces—abstract methods. In order to meet the intent of the Subject interface, I created an abstract class that has abstract methods for attaching and detaching Observer objects. However, I also included a concrete notify() method along the lines suggested.

< ?php
abstract class Subject
{
    //Abstract attach/detach methods
    public abstract function attach(Observer $observer);
    public abstract function detach(Observer $observer);
 
    //Concrete protected arrays and  public method
    protected $observerSet=array();
    protected $dataSet=array();
    public function notify()
    {
        foreach($this->observerSet as $value)
        {
            $value->update($this);
        }
    }
}
?>

The idea of the Observer is to have a concrete Subject class (or classes), and have Observer objects subscribe to the data in the Subject. It’s something like a News Service used by Television, Radio, Newspapers and News Blogs. The News Service is the Subject and the news outlets are subscribers — concrete Observers. Notice in Figure 1 that the arrow from the Subject to the Observer ends with a solid ball. That means that the relationship is one (Subject) to many (Observers.) In the example provided, you can add data to a hypothetical “inventory” program that then forwards it to a Subject, and the Subject makes it available to different Observers. In this case there are only two: one that uses the Subject information to create a bar chart, and another that uses the data to display a data table.

Next, look at the ConcreteSubject named, HardwareSubject.

< ?php
class HardwareSubject extends Subject
{
    public function attach(Observer $observer)
    {
        array_push($this->observerSet,$observer);
    }
 
    public function detach(Observer $observer)
    {    
        $counter=0;
        foreach($this->observerSet as $value)
        {
            if($this->observerSet[$counter]==$observer)
            {
                unset($this->observerSet[$counter]);
            }
            $counter++;
        }
    }
 
    public function getState()
    {
        return $this->dataSet;
    }
    public function setState($data)
    {
        $this->dataSet=$data;
    }
}
?>

As an extension of the Subject abstract class, it must implement the attach/detach (think subscribe/unsubscribe) methods. The inherited notify() method is concrete; so it’s available for use with no modifications—not seen in the class. The getter/setter methods are used to make the data to the attached Observers (subscribers)— getState() and the setState($data) methods receives the data to be made available to subscribers. In this example, the data are made available through a UI directly, but the data could come from any source—especially a MySQL database. As you will see, the data for the dataSet array (inherited from Subject) gets it data from the array storing the data provided by the Client.

The Observers

The real work horses for this pattern are the concrete Observer objects. The concrete subject takes the data and tosses it out to the subscribed (attached) observers and they’re the ones who really do something with the data from the Subject. Take a look at the Observer interface:

< ?php
interface Observer
{
    function update(Subject $subState);
}
?>

As you can see, it’s quite simple with a single method that expects a Subject object as an argument. However, this part can be a bit tricky since the notify() method of the Subject interface includes an update call that uses the current concrete subject as a parameter. That is, the update($sub) is called from a Subject object and includes itself in the form of a $this statement in the parameter.

The Bar Chart
The concrete Observers can be as simple or complex as you want. I went for medium complex. First, take a look at the BarChartObserver. It takes the Subject’s data and makes bar charts using SVG graphics.

< ?php
class BarChartObserver implements Observer
{
    private $obState=array();
    private $barChart;
    private $bar;
    private $color;
    public function update(Subject $subState)
    {
        $this->obState=$subState->getState();
        $this->makeChart();
    }
 
    private function makeChart()
    {
        $this->color=array('#0D3257','#97A7B7','#B2C2B9','#BDD6E0','#65754D','#C7DBA9');
        $spacer=0;
        $maxVal=max($this->obState);
        $mf = function($x){return 220/$x;};
        foreach($this->obState as $value)
        {
            $adjSize=$mf($maxVal) * $value;
            $this->buildChart($spacer,$adjSize);
            $spacer+=36.6;
        }
      }
 
      private function buildChart($pos,$barSize)
      {
        $cc= array_pop($this->color);
        $base = 220-$barSize;
        $SVG ="<svg width='220' height='220' viewBox='0 0 220 220'>";
        $this->bar ="<rect x=$pos y=$base width='36.6' height=$barSize fill=$cc stroke='#888' stroke-width='1'></rect>";
        $this->barChart=$SVG . $this->bar;
        echo $this->barChart;
      }
}
?>
</svg>

Whenever making charts, you have to take in several considerations. I’ll touch on two here. First, the values have to be relative to the largest element in your numerical array. This can be used to set up relative sizes by using the max() method with your array, and the little lambda function stored in $mf. When iterating through the array with a foreach() loop each value is set to the size of the window (220). By using the lambda function with the maximum value as a parameter, the maximum value divided is by 220 is the factor, and that value is multiplied by the factor times the actual value of the data point. That gives you values that will fit in the 220 pixel window relative to the size of the maximum value. (If you have a spiked maximum value, the other value tend to flatten out on the chart.)
Continue reading ‘PHP Observer Design Pattern: The Basics’

Share

PHP-MySql Universal Connection: The Try/Catch Exception Tweak

universal2In 2012, I posted a little piece on a PHP-MySql connection utility. Since the time of the original posting, I’ve used that utility again and again. It’s been used in my own applications (many of which have appeared on this blog), with my clients, and with others who I was able to help. Other than minor tweaking with the replacement of a conditional if statement with the try/catch exception, it has remained largely unchanged.

Recently, John Slegers from Belgium provided some thoughtful comments for refactoring the little utility. (Being a big Salamander fan [Netflix], I listen to what the PHP folks from Belgium have to say!) His comments inspired some re-thinking, and while I made some changes, they were minor and along different lines. Download the revised version and take a look at it:
Download

Object Thinking

In developing software, I think in terms of objects and object structures. That is, rather than thinking in lines of code and statements, I find it easier to think in terms of what an object does and how it fits into a larger object structure rather than how statements are used. So, in using PHP with MySql, I tend to view connections to the database as something an object handles and I don’t need to worry about otherwise. Recently I was working on an Observer design patter using the built-in SplSubject and SplObserver. It occurred to me that the concrete subject might pull data out of a MySql database, and so I just popped a copy of the universal connect utility in the folder and it’s all set. Figure 1 illustrates it use:

Figure 1: Adding connection utility to small observer

Figure 1: Adding connection utility to small observer

The utility is very small—a single interface and class—but it’s very useful.

The Code

First of all, an interface stores connection information in constants, and as long as you’re using the same database, you can re-use the values. The single method is defined as public and static so that a single line of code can launch the method that uses the constants for connection. It is largely unchanged from the original.

<?php
//Filename: IConnectInfo.php
interface IConnectInfo
{
	const HOST ="localhost";
	const UNAME ="bart";
	const PW ="itchy";
	const DBNAME = "scratchy";
 
	public static function doConnect();
}
?>

The UniversalConnect class does all of the work for making a connection using the constants in the interface. Again, static declarations mean that the class need not be instantiated to use the method:

<?php
ini_set("display_errors","1");
ERROR_REPORTING( E_ALL | E_STRICT );
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);
		try
		{	
			self::$hookup;
			//Comment out / Uncomment following line for develop/debug
			echo "Successful MySql connection:<br />";
		}
		catch (Exception $e)
		{
			echo "There is a problem: " . $e->getMessage();
			exit();
		}
		return self::$hookup;
	}
}
?>

The try/catch exception stops everything cold if the connection is not made, and the Exception provides the information you need to correct it. If the try is successful, it returns the connection to the client.

That’s pretty much it. During development, I like to see the Successful MySql connection message, but once everything is ready to go, I just comment it out. The following little class tests the connection and should not be included in a development folder:

<?php
include_once('UniversalConnect.php');
class UseMySQLConnect
{
	private $doConn;
 
	public function __construct()
	{
		try
		{
			$this->doConn=UniversalConnect::doConnect();
			echo "Succesful connection";
			$this->doConn->close();
		}
		catch (Exception $e)
		{
			echo "There is a problem: " . $e->getMessage();
			exit();
		}
	}
}
$worker=new UseMySQLConnect();
?>

The line,

$this->doConn=UniversalConnect::doConnect();

takes care of all connection steps for you, and instead of having your code piled up with the same code block required by mysqli() (PHP’s improved MySql function), you just make sure the include_once makes the UniversalConnect class available, and you can use it wherever you need MySql.

Share