4

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?

  • 5
    When you say that a Singleton is 'not ideal' according to your research, do you mean that you found that it doesn't actually fit your problem/requirements? Both your description and the words 'classic Singleton' make it seem like you have a legitimate case for a Singleton and have just been warned off too strongly by internet dogma. – Snagulus Nov 25 '13 at 16:45
  • Snagulus - I believe I do have a case for a Singleton. However, I am constantly checking for best practices, and there is a lot of negative connotation with Singletons in PHP. I just wanted to do my due diligence and make an informed decision. – JRizz Nov 25 '13 at 16:47
  • 1
    @Snagulus Since the singleton accesses external mutable state (a database), a classical singleton is a bad solution. Still it might be the best available solution in this context. Sometimes one has to choose the smallest evil, which might be a singleton here. – CodesInChaos Nov 25 '13 at 16:48
  • Ah, I assumed this was data that was essentially considered immutable during the runtime since it was only loaded once at startup, but I see now that wasn't part of the description. – Snagulus Nov 25 '13 at 16:52
  • 3
    I think the key part is "This class is a classic Singleton - it only needs to be instantiated once". This is the problem with most people's understanding of singletons. You don't use a singleton when it only needs to be instantiated once, you use a singleton when it MUST only be instantiated once. In all other cases you have a crappier version of a global variable. – Chewy Gumball Nov 25 '13 at 17:44
3

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.

0

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.

-1

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.