vendredi 21 août 2015

PHP Application settings in database

How can I access application settings in my objects while remaining DRY?

I'm not referring to things like database credentials or API keys, those are kept in environment variables. The settings I'm referring to here are things like:

WORK_DAY_START_TIME     04:00:00
MAX_HOURS_PER_DAY       13
ALLOW_DAY_CROSSOVER     false

The settings affect business logic, are global to the application, and varies across different organizations. The intended users are managers who may not be technical so therefore there's a user interface that allows them to change settings.

The values are persisted into a database (though the persistence medium is irrelevant here as I can easily read from a XML/INI/JSON/YAML file).

Here's a simple class for accessing the settings (it's a bit more than that but for the purpose of this question it's sufficient):

<?php

class Settings implements \ArrayAccess
{
    private $settings = array();

    public function __construct() {
        // get settings from DB and put them in $this->settings
    }

    public function offsetGet($key) {
        return $this->settings[$key];
    }
}

// In the entry point file:
$settings = new Settings();

I need the value when checking things:

class Shift extends EntityObject
{
    private function isValid() {
        // For illustrative purposes only
        return !$settings['ALLOW_DAY_CROSSOVER'] && $this->start < $settings['WORK_DAY_START_TIME'] && $this->end < $settings['WORK_DAY_START_TIME'];
    }
}

Here are some options I came up with:

  1. global $settings or its alternative $GLOBALS['settings']. This relies on a global variable so not good.
  2. Make Settings a singleton. Pretty much the same problem, it's hard to do unit testing with.
  3. In the constructor of each class, instantiate a Settings to get the settings. This seems like a lot of overhead especially when the settings are already loaded.
  4. Pass the instance of Settings into the constructor of each object that requires settings (so basically all the objects). This sounds like dependency injection if I understand it correctly but it seems repetitive?

How should I approach this problem?

I think I'd run into the same problem if I used Zend_Config.

A related question is $settings array or Config Class to store project settings?.

Aucun commentaire:

Enregistrer un commentaire