I’d like to have a library class that maintains state across the same request. My use case is that I want to pass ‘messages’ to the class, and then call them at any time from a view. Messages can be added from any part of the application.
I had originally done this via static methods, which worked fine. However, as part of the lib, I also need to call __construct and __destruct(), which can’t be done on a static class.
Here’s a very simple example of what I am trying to do:
class Messages
{
private static $messages = array();
public function __construct()
{
// do something
}
public function __destruct()
{
// do something else
}
public static function add($message)
{
self::$messages[] = $message;
}
public static function get()
{
return self::$messages;
}
}
I can then add messages anywhere in my code by doing
Messages::add('a new message');
I’d like to avoid using static if at all possible (testability). I have looked at DI, but it doesn’t seem appropriate, unless I’m missing something.
I could create a class (non-static) instead, but how do I then ensure that all messages are written to the same object – so that I can retrieve them all later?
What’s the best way to tackle this?
I looks like you could benefit from using the Singleton pattern – it is designed for an object that must have only one instance throughout a request. Basically, you create a private constructor and a static method to retrieve the sole instance. Here is an example of a singleton that will do what you describe.
Since the constructor is private, you can only create a
Messagesobject from within a method of the object itself. Since you have a static method,instance(), you can create a newMessagesinstance from there. However, if an instance already exists, you want to return that instance.Basically, a singleton is the gatekeeper to its own instance, and it stubbornly refuses to ever let more than one instance of itself exist.