I have been researching this extensively, and I am stuck. I am writing a Drupal module that uses a class that I have created. This class is a classic Singleton – it only needs to be instantiated once, since it is assembling a bunch of data from a database. Note that my potential Singleton will not update any data in the database – it will just read from existing data. Also, note that processes outside the context of my program may update the data.
I know the take home answer here is ‘use Dependency Injection’. However, I can not use Dependency Injection – Drupal uses hooks, and these hooks accept certain parameters. I.e., I can’t (to my knowledge) insert a object that way.
I should point out that testing is a concern of mine as well (although testing my module in Drupal has had its own series of challenges). However, I am willing to accept that a Singleton may be the lesser of two evils here.
Here is an example:
function mymod_block_view($var) {
//$var is required by drupal
$obj = new Object()
....
}
function mymod_block_info() {
...
$obj = new Object()
}
My options right now are to use a global variable (not ideal) or a Singleton (according to my research, also not ideal, but may be my only option). Do I have any other options, besides declaring a new variable object inside each function?
14
You seem to be stuck between a rock and a hard place. Neither a global variable nor a singleton are very “good” practice. The main issue I see is that singletons are not really to be used when you only need to instantiate it once, but instead when you MUST only instantiate them once. For example, you may only need one instance of a scoreboard in a game, but nothing breaks when you have two or three instances (if done well). Writing to a log file across multiple threads might break if writes are not threadsafe (they almost assuredly won’t be natively), and so having multiple instances of the file handle could be destructive. This is a better reason for having a singleton.
Since I don’t believe you have a real use case for a singleton, I suggest a global variable. That is essentially what a singleton would be anyway, here, but you gain the advantages of being variable. This would make switching between databases mid-execution simpler, for example, and you might even find it easier to test than a singleton.
Use a database for data collection purposes. A kind of production pipeline of data flow. Application level data, user level data, session level data (same page in two tabs). A NoSQL database would do nicely, but a classical database might be more known and faster.
It seems to me that you are trying to Apply the best practices for Java (multi-threaded, long lasting processes etc., general purpose language) to PHP (Single thread, processes initialized on each request, specialized for delivering HTML pages).
There are good reasons to avoid singletons in Java, but I do not see how they apply in the single threaded short life cycle of a php program.