Get up to 80 % extra points for free! More info:

Lesson 11 - Static class members in PHP pt. 3 - do's and don'ts

In the previous lesson, Static class members in PHP pt. 2 - constants, we went into further detail in regards to class members and introduced constants. In today's lesson, we will wrap up with static members. We'll go over static registries, database wrappers, and discuss when to use static members.

Static registry

A static registry is a class that only contains static properties. Typically, this type of class is used to store application settings. This way, all of the settings (database password, website URL, default language) can be shared by the entire application. In non-object-oriented applications, people would use global variables instead of static registries. Here's what our static registry looks like:

class Settings
{
    public static $dbCredentials = array(
        'username' => 'root',
        'password' => ''
    );

    public static $url = 'localhost';

    public static $language = 'en';

}

We would now be able to retrieve the application settings from anywhere in the application and/or change them anywhere as well:

if (Settings::$language != 'en')
    $background = "background_english.png";

Using static registries is, again, very controversial. The idea of using static registries for storing application configuration is not a bad one at that. However, people often use them for storing various object instances. Every object would then be accessible from the registry everywhere, which is just wrong. The real question is, is an application even still object-oriented when it is stripped of all encapsulation?

Database wrapper

A common and meaningful use of static members is as database wrappers. I expect that you all no longer work with outdated non-object-oriented database drivers (like the mysql_query() function). As you know, it's best to work with databases using OOP and the PDO driver (PDO stands for PHP Database Objects). Using the PDO driver is simple, a class instance is created, which then connects to a database. Since we don't want to connect to the database over and over and again, we share this single connected instance over the entire application (using static members). Come to think of it, we haven't worked with databases for a while now. We'll set some time aside for it in the next lesson, where we will also describe wrappers in detail.

Controversy

As I've mentioned before, static members are one of the most controversial topics in object-oriented programming. If you think about it, using static members technically break OOP's principles because they're accessible from anywhere and without an instance. If you have a few static classes here and there, something less than four, and the rest is non-static, you'll be alright. However, if every other class is static, you will have to re-structure your application.

There's a rule, that says that every application can be written using only pure object-oriented programming, without static members. Some people believe that programming languages should not support static members at all. Honestly, using them isn't that big of a disaster, however, people often use static members inaproprietly. For this reason, I will dedicate the rest of this lesson to go through the proper and improper uses of this technique.

Proper usage of static members

When you think about it, the examples we made all had similarities. They were all either utility methods or helper classes, which are often used in a variety of places in an application. There is no point in creating an instance from a class because we would end up using a single instance anyway (one Math, one Console, one Database...). In object-oriented CMSs, we use static members when writing what we call helpers, short utility methods used when formatting output. For example, we have a helper here at ICT.social used for printing the current date using words:

echo('Today is :' . DateHelper::words($date));

Another example is our math library, which doesn't even have an inner state. Since all it is is a group of utility methods.

We can also store the current user instance, the one that is currently signed-in, the currently displayed article, etc. using static properties. Again, all of these things are shared and required between classes.

Static members in respected projects

You'll find static members in the base object-oriented libraries in respected programming languages, i.e. Java or C# .NET. Static members, are used in these languages for utility methods, such as displaying a simple message or printing text into the console:

Console::writeLine("Text");
MessageBox::show("Wrong password");
$result = Database::query("SELECT * FROM `human`");

We only have one console and work with it in an enormous amount of classes, so it would only sense to make its class static. The same goes for databases, an application almost always uses a single database from many different places.

Wrong usage of static members

If you find yourself thinking about whether or not you should use static members, don't use them :) In 90% of cases using them is pointless. Don't use static members in cases other than those that we mentioned. Unless you are creating some sort of system class, one that would be used everywhere, your classes should not be static.

Even for a HumanManager class that includes methods like signUp(), remove() etc., should not be static. It's better to just create an instance of the aforementioned class whenever you need to work with people. Don't ever make static galleries, static people, etc. I split this topic up into three lessons, mainly to teach you all to read static code. Although, I never really had you write it, you'll definitely encounter static members in other people's work for sure. Despite the fact that they should not be using them.

Passing dependencies and dependency injection

Static members are also used when passing dependencies, i.e. classes that are necessary for other classes in order for them to work properly (a database class or application settings). There are entire books dedicated to dealing with object dependencies in applications, where you will find millions of approaches. Passing dependencies is one of the most discussed topics in OOP. It's hard to say whether beginners should even pass dependencies using static members or using complicated design patterns, I find static members to be simple and clear if used correctly.

Usually, in a system that consists of a few dozens or so classes, you can use static members without it hurting the application. Well known frameworks do it, even I do it. As the number of dependencies increases (especially with third party libraries, which I try to use minimally) along with a number of static classes. When you share more than a few items statically in an application, it's better to abandon static members altogether and pass exactly what a class needs thru the constructor. This way, the application stays under control and won't turn into a static class spaghetti monster, where its dependencies aren't apparent. For that reason, some programmers recommend not to use static members altogether.

A good way of passing dependencies automatically without static members is called Dependency Injection (shortly DI), we will talk about later on. Another way to pass dependencies, that I found while I creating computer games, is to create shared instances inside a container and to pass the container through whichever objects' constructor afterward (this approach is called a service locator). This way, we don't use static members and can still access the Container instance easily from a Hero instance per se. In other words, we'd have access to all of the required data, i.e. a map, other objects, game settings, database instances, etc.

Dealing with dependencies in a real system will be explained in further detail in the next couple of courses. We are now done with static members. In the next lesson, Solved tasks for OOP in PHP lessons 9-11, we will go over the basics of working with databases by using PDO driver.

In the following exercise, Solved tasks for OOP in PHP lessons 9-11, we're gonna practice our knowledge from previous lessons.


 

Previous article
Static class members in PHP pt. 2 - constants
All articles in this section
Object-Oriented Programming in PHP
Skip article
(not recommended)
Solved tasks for OOP in PHP lessons 9-11
Article has been written for you by David Capka Hartinger
Avatar
User rating:
No one has rated this quite yet, be the first one!
The author is a programmer, who likes web technologies and being the lead/chief article writer at ICT.social. He shares his knowledge with the community and is always looking to improve. He believes that anyone can do what they set their mind to.
Unicorn university David learned IT at the Unicorn University - a prestigious college providing education on IT and economics.
Activities