Is configuration with arrays a bad smell?

Something I see fairly often in PHP, where OOP / classes are concerned;


$options = array (
'name' => 'Harry Fuecks',
'favoritecolors' => array ('red','green','blue'),
'favoritefoods' => array (
'breakfast' => 'English Breakfast',
'lunch' => 'Steak and chips',
'dinner' => 'Tandori Chicken',
),
'etcetc' => 'aarrrgh!'
);

$person = new Person($options);

In other words a giant array used to “configure” the runtime behaviour of an object.

For me this is a bad smell. For a start it usually means there’s some giant class method in there somewhere which deals with “parsing” the array and reacting accordingly. More importantly, think it’s a nightmare for the user – arrays are hard to document and easy to get wrong when you’re hand-coding one.

I’d much rather see something like;


$person = new Person();
$person->name('Harry Fuecks');
$person->addFavColor('red');
$person->addFavColor('blue');
$person->addFavColor('green');
$person->addFavFood('breakfast','English Breakfast');
$person->addFavFood('lunch','Steak and Chips');
$person->addFavFood('dinner','Tandori Chicken');

The methods are easy to document (with phpDocumentor) and, IMO, it’s alot easier to test / use. The API makes what’s happening explicit.

Otherwise, wise use of parse_ini_file(). PHP can parse an ini file into variables faster than it can parse and execute an equivalent PHP script….

Rant over.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • johnny

    Equally as well, you could have:


    $person->addFavColor(array('red','blue','green'));

    Then have the $person class check if the received argument is an array or not. Arrays are indeed useful, so give yourself the freedom to use them. Just keep the “bad smell” out, as Fuecks puts it ;)

  • mitchell perilstein

    Two comments.

    First, I think the array argument method is a poor way to handle named arguments. Wouldn’t this be nicer: $my->foo(‘breakfast’ => ‘donuts’, colors => array(‘red’,blue’));
    Maybe the language should support these.

    Second, as devil’s advocate. Here is one argument in favor of arguments as a separate array. The array is a single manipulatable object that can be set, fiddled with and passed around, then given to its final consumer. You can’t do that with named arguments. It lets you manipulate these in a generic way, instead of everyone knowing that objects get/set methods.

  • Ammar Ibrahim

    What about configurations in Applications written using procedural Code.
    Isn’t writing Constants using ‘define()’ the best method, but configurations should be loaded only when needed, because sometimes people pollute global space with global configurations for everything….

  • Joseph Scott

    I think I see where you trying to go with using an object to store. I will disagree though, I still believe an array will do the job. Based on your example, my style has been something like this:


    $CONF['name'] = 'Harry Fuecks';

    $CONF['favoritecolors'] = array(
    'red',
    'green',
    'blue
    );

    $CONF['favoritefoods'] = array(
    'breakfast' => 'English Breakfast',
    'lunch' => 'Steak and chips',
    'dinner' => 'Tandori Chicken'
    );

    $CONF['etcetc'] = 'aarrrgh!';

    Then instead of passing this to each object, simply use ‘global $CONF’ if I need to make use infomation stored in $CONF.

  • sleepeasy

    I can’t agree more… I find it much easier to have methods for each ‘setting’ than having to pass an array – and what’s worse is when you have to passnested arrays – badbadbad. To me it points to lazyness on the part of the developer in that they couldn’t be bothered to write a few more methods.