Apologies for a long rumination post. I'm trying to move rotten old code to a shiny new project and hope to eliminate the pain I've been dealing with. It's also a fresh new year and a good time to sharpen the skills...
I have a lot of configuration values that need to be accessible throughout my project:
Cloud API credentials (CDN user name & key, etc.)
Payment gateway credentials (Paypal, Authorize.net, etc.)
Mail credentials (Sendgrid or MailChimp, etc.)
Inumerable site-specific configuration settings (e.g., CURRENT_SPECIAL_OFFER_SRC_FILE)
Note that these are above and beyond your usual site configuration settings (db credentials, file system locations, domain information, etc.).
My question is this: How should one deal with all these various types of configuration such that they are easily accessed in code? This may seem like a simple question, but I'm not really looking for a simple answer. I have revisited old posts here on phpbuilder.com, I have checked out CodeIgniter's Config Class, and I've been looking at a couple of books that both mention Martin Fowler's discussion of the Registry pattern. Anecdotal experiences and solutions are welcome.
One of the biggest questions I have is whether a registry class should be global/canonical/static across my entire project. This would be both good and bad.
GOOD: One registry we can always locate and retrieve the authoritative value from. The one, true registry would eliminate a lot of confusion in a project.
BAD: Global objects are vulnerable to name collisions and tend to undermine the modularity of one's code, reducing its reusability and ability to place nice with other code. Global/static/shared variables can lead to race conditions or deadlock or other nastiness in multithreaded/concurrent execution scenarios. (Other?)
Another giant question is that of persistence mechanism. I.e., should I use config files or a database to specify config values?
DB PROS: easy to set up a 'settings dashboard' where an admin can alter these settings via some web interface. Writing a single new value is easily accomplished by writing one or more records. Easy to retrieve values via lazy loading.
DB CONS: Requires db connectivity, dependent on db connection for operation which would essentially preclude settings for any operations that should proceed in the absence of DB connectivity (um LOGGING cough cough), specification of arrays or objects or other '3-d' data structures requires trickery or some kind.
CONFIG FILE PROS: can lead to convenient organization by separating settings into distinct config files or otherwise utilizing fileystem as means of dividing namespace via folders-and-files (think Windows Registry). works even if DB connection fails completely. Easy to define '3-d' data objects like arrays and objects and so on.
CONFIG FILE CONS: difficult to change a single value as it'd be tricky to rewrite the file. no lazy loading really as you kinda have to parse the entire config file. performance? caching, etc.?
Also, it should be pretty apparent that some of these values (payment gateway credentials, Amazon EC2 credentials, mail credentials) are sensitive information. Security is a great concern here. Some have suggested that such credentials are encrypted. It makes me wonder at what point they get encrypted and at what point they get decrypted and which ones get encrypted and which don't and of course would this even make sense because the encryption key would have to live on the server anyway.
There's also the question that my code may end up being tightly coupled to this Registry concept. What is a reasonable way to limit one's exposure to this tight coupling issue without jumping through a zillion hoops? I'm inclined to think in an MVC project that limiting Registry access to my Controller is one way, but I worry that might be extreme. Hard to say until I'm deeper in. Perhaps models might also access it? sigh
There's a fairly interesting example here that contains some snarky comments and also links to discussions about Registry vs. Dependency Injection.
All discussion and advice is welcome.