2

I have a script (a small and simple CMS-like system), which I'm always working on and use it for client sites. Since clients have different requirements, I've implemented a module system which allows me to modify/or add functionality to the CMS, without having to modify the CMS script.

How can I implement a configuration system that allows me to change the default settings of the main CMS from the modules?

For example the CMS has by default two menus: $menu = array('menu-1', 'menu-2'); How could I override this setting from the modules?

One solution I've thought of is to use constants and serialize/unserialize:

defined("BLA") or define("BLA", serialize(array(
 'boo' => 'stuff',
 'foo' => array('1', '2', '3'),
 'moo' => true,
 ...
)));

So I could easily override this setting in the module initialization function which runs before the constant is defined in the CMS.

Then I'm using these constants everywhere inside my scripts, like:

$bla = unserialize(BLA);
...
foreach(unserialize(BLA) as $key => $value)...

Another alternative would be to use a global variable, but people say it's bad to use global.

So are there any better solutions to what I'm looking for?

10
  • 1
    Why are you doing that? May as well just define a global array if you're going to take that route. Alternatively, you could use a config library which allows you to store arrays as config values. Commented Feb 3, 2011 at 16:26
  • because I need a array constant :) And I don't want to use global variables Commented Feb 3, 2011 at 16:27
  • Are you using an MVC framework? Commented Feb 3, 2011 at 16:28
  • no. is there any other way than global variables to store data like I want and be able to access anywhere? Commented Feb 3, 2011 at 16:31
  • 2
    What about make a function returning that array? Commented Feb 3, 2011 at 16:31

4 Answers 4

5

I would recommend using a class with static variables. More or less the same result, but no need for unserializations and you can actually use the variable, not a temporary one.

// My Constants
class MCo { 
    public static $BLA = array(
        'boo' => 'stuff',
        'foo' => array('1', '2', '3'),
        'moo' => true,
        // ...
    );
}

echo MCo::$BLA['boo'];

foreach (MCo::$BLA as $key => $value) {
    // ...
}

EDIT: ircmaxell has a point, consider this then

// My Private Constants
class MPCo { 
    private static $_BLA = array(
        'boo' => 'stuff',
        'foo' => array('1', '2', '3'),
        'moo' => true,
        // ...
    );
    public static BLA() {
        return self::$_BLA;
    }
}

foreach (MPCo::BLA() as $key => $value) {
    // ...
}
Sign up to request clarification or add additional context in comments.

6 Comments

Slightly different concept, since a public static variable is mutable, whereas constants are not. (MCo::$BLA['foo'] = 'bar';)... But possibly a decent alternative.
Yeah, kind of the same concept I suggested as a comment to her - using a singleton.
You could make it an read-only array by deriving ArrayObject and making offsetSet() a NOP.
Sounds interesting. The reason I wanted to use constants is because I can "override" the default values by defining them earlier in another script (and I define them in the current script only if they are not defined before). can I do this with your method?
@inti: better, but since PHP doesn't support array dereferencing, that would be awkward to access direct member variables of the array (aka MPCo::bla()['foo'] won't work). It's better, but still has some issues...
|
1

If it's going to be a lot of static data that you plan on storing in the array, why not store it in a config file? Alternatively, you could load it from a DB, but config is better for this.

And the other option is to do what @inti suggested in his answer.

1 Comment

because this is not the real "config", it's more like a code configuration :) the real configuration uses the database. Basically I have a script1 (a CMS-like system that I use for different clients) which has these constants defined. Then I create other scripts (2,3..) which may use script1. So I can define these constants in script 2,3 etc(which are like "modules" for this simple CMS), to change this config in script1... This way I don't have to modify script1 for each client, I can do it from the modules... Could this be done with a singleton class like you mentioned? If so, how?
1

The first question I'd ask is why do you need an array in a constant. There is likely another solution to your problem that's just as good, but doesn't need arrays.

One alternative that would be better is to create a configuration object, and pass that around. That way it's still testable since it's injecting the dependencies and doesn't have a performance impact of working with serialize.

$config = new StdClass();
$config->boo = 'stuff';

doSomething($config);

Constants aren't much better than global variables. In fact, they are worse in some respects since it's very hard to test with them since once you define a constant, you can't change it. So in the pursuit of good testable code, constants are not good. If you're dependent on constants other than for dealing with magic numbers or filesystem paths, you might want to rethink your approach (Even magic number constants might be better handled with a configuration class)...

1 Comment

I need it to get the configuration. this configuration is not retrieved from the db, the values are set in the script, just like a constant is set
1

This is really unnecessary, just use a variable instead of a constant, it will be simpler, clearer and I would guess better performing.

1 Comment

I've rewritten the question to explain better what I'm looking for :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.