How to Limit the Number of Class Objects using PHP Singleton and Multiton Design Patterns - TonTon PHP Singleton Trait New Generation package blog

Recommend this page to a friend!
  All package blogs All package blogs   TonTon PHP Singleton Trait New Generation TonTon PHP Singleton Trait New Generation   Blog TonTon PHP Singleton Trait New Generation package blog   RSS 1.0 feed RSS 2.0 feed   Blog How to Limit the Numb...  
  Post a comment Post a comment   See comments See comments (1)   Trackbacks (0)  

Author:

Updated on: 2021-04-29

Posted on: 2021-04-29

Package: TonTon PHP Singleton Trait New Generation

Singleton and multiton are software design patterns that can be used to limit the number of objects a given class that can be created within the life time of current PHP script.

These design patterns are very useful for PHP developers in certain circumstances.

Read this article to learn why the singleton and multiton can be useful in PHP projects and how you can use them in general purpose project and in particular in WordPress projects.




In this article you will learn:

What is this Article About

Singletons as a Simple Design Pattern

What Are Multitons

What if I want to Use a Specific Number of Class Objects?

Removing Redundant Code Using PHP Traits

How to Download the TonTon PHP Singleton Trait Package or Install it With PHP Composer


What is this Article About

If you have been following our posts, you probably noticed that this content is definitely not for those looking for the "best plugins" for WordPress or trying to find ways to troubleshoot problems that are often caused by those same plugins.

At the same time, we are not targetting experienced and top notch PHP developers or programmers, although they can always gain good knowledge, like us, from reading interesting new approaches and ideas on coding.

But no, if you are willing to really understand WordPress and other frameworks, as well as PHP, in a way that you can not find the solutions, but think about them, so you are definitely the one we have been writing for.

Singletons as a Simple Design Pattern

If you are relatively familiar with PHP and even WordPress coding, you already heard about the term Singleton. Maybe you heard something on Multiton, or even design patterns in PHP. If not, let's quickly recap.

Before explaining the Singleton briefly, let's give an overview about the design patterns. The Singleton is one of them.

Singleton is a design pattern for creating objects which assures that only one object of its kind exists simultaneously. A lot of developers consider the Singleton pattern an anti-pattern, but sometimes it is pretty handy, even though it may affect the code modularity.

Singletons in PHP usually make use of a static property that holds a single instance of an object. This is an example of a very simple Singleton class:

final class Singleton
{
    private static ?Singleton $instance = null;

    /**
     * gets the instance via lazy initialization (created on first usage)
     */
    public static function getInstance(): Singleton
    {
        if (static::$instance === null) {
            static::$instance = new static();
        }

        return static::$instance;
    }

    /**
     * is not allowed to call from outside to prevent from creating multiple instances,
     * to use the singleton, you have to obtain the instance from Singleton::getInstance() instead
     */
    private function __construct() { }

    /**
     * prevent the instance from being cloned (which would create a second instance of it)
     */
    private function __clone() { }

    /**
     * prevent from being unserialized (which would create a second instance of it)
     */
    private function __wakeup() { }
}
PHP

In the WordPress context, especially while developing a plugin, sometimes singletons can be useful for logging features, assuring that events are triggered and expected behaviors occur on plugin's installation or removal, or even in the plugin's main class or init class.

However, many plugins seem to use it singletons too much. Sometimes we want to limit instances, but not necessarily to a single one. And other times, we want to create class objects just a few times and also want make sure each one of the instances is distinct. For such cases there is a have a related design pattern called Multiton.

What Are Multitons

Well, if we wanted to limit the number class objects that can be created, you may ask why designing a pattern that allow creating multiple class objects?

The Multiton can limit the class objects that are created not just in quantity. It can also associate a named key to each unique class object that is created.

Our implementation of a Multiton is similar to a Singleton, but with two main differences:

  • The static property $instances is an array.
  • The instance() or getInstance() method receives an argument.

Regarding the last Multiton aspect, the method that gets the instance would look like this:

/**
     * gets the instance with the given name and uses lazy initialization.
     *
     * @param string $key
     *
     * @return Multiton
     */
    public static function getInstance($key)
    {
        if (!array_key_exists($key, self::$instances)) {
            self::$instances[$key] = new self();
        }

        return self::$instances[$key];
    }
PHP

What is the intention of this approach? Some classes may be used in different instances, for similar tasks that are not exactly same, like for instance multiple loggers objects or different PDO objects to access two or more existing databases, such as in the case of hybrid applications using MySQL and SQLite.

In WordPress, that could be handy for accessing two different MySQL databases like in sites using HyperDB, for example. Multiple logger objects can also be useful in many situations using a Multiton.

What if I want to Use a Specific Number of Class Objects?

Consider cases that you want to use not just a single class object, nor multiple class objects, but rather a specific number of instances defined by your application.

Multitons could be used, but you would need to have a way to limit instances when they reached the maximum number that you allow to exist.

That made us created a useful derivation of the Singleton pattern that we called the Limiton. In this case, on top of a key for each instance, we want to set a variable, which provides the maximum number of instances. Then check the count of instances stored in the $instances property before creating any new object. Something like this:

/**
     * @var reference to limiton array of instances
     */
    private static $instances = [];

    /**
     * @var limit of concurrent instances of the class
     */
    public static $limit = 2;
    
    /**
     * Creates a new instance of a limiton class flagged with a key.
     *
     * @param $key the key which the instance should be stored/retrieved
     *
     * @return self
     */
    final public static function instance($key)
    {
        if(!array_key_exists($key, self::$instances)) {

            if(count(self::$instances) < self::$limit) {
                self::$instances[$key] = new self;
            }
              
        }
        
        return self::$instances[$key];
    }

    /**
     * Sets the maximum number of instances the class allows
     *
     * @param $number int number of instances allowed
     * @return void
     */
    public function setLimit(int $number) {

        self::$limit = $number;
    }
PHP

This simple and straightforward approach solves the issue. A Limiton could be useful in a number of situations. It limits the number of class objects that can be created, like the Singleton, but keeps a flag on each allowed instance that is created.

Besides that, a method setLimit() provides additional flexibility by allowing to modify the number of concurrent object that can exist at the same time.

Removing Redundant Code Using PHP Traits

Nothing worse than finding an application or plugin in which at least a dozen of classes start with a Singleton inside them. That is a tragic and unnecessary copy and paste effort.

If you are familiar with PHP traits, that has been a smart way of avoiding code duplication. So let's use traits inside our classes to apply Singletons, rather than pasting it on every situation required.

Of course we provide a library for that: you can just use traits. a Singleton, a Multiton and our Limiton.

How to Download the TonTon PHP Singleton Trait Package or Install it With PHP Composer

The TonTon PHP Singleton Trait package is available for you to download as a ZIP archive by going to the download page or install it using the PHP Composer Tool by going to the installation instructions page.




You need to be a registered user or login to post a comment

1,578,438 PHP developers registered to the PHP Classes site.
Be One of Us!

Login Immediately with your account on:

FacebookGmail
HotmailStackOverflow
GitHubYahoo


Comments:

1. singleton initializer - adriano ghezzi (2021-04-29 11:47)
initialize singleton... - 0 replies
Read the whole comment and replies



  Post a comment Post a comment   See comments See comments (1)   Trackbacks (0)  
  All package blogs All package blogs   TonTon PHP Singleton Trait New Generation TonTon PHP Singleton Trait New Generation   Blog TonTon PHP Singleton Trait New Generation package blog   RSS 1.0 feed RSS 2.0 feed   Blog How to Limit the Numb...  

For more information send a message to info at phpclasses dot org.