4
votes
\$\begingroup\$

I am seeing it more and more.

Which do you think works best and why?

This:

$config = array(
'param1'=>'abc'
'param2'=>'dfg'
);

new Class($config);

Or:

new Class('abc','dfg');
\$\endgroup\$

locked by Jamal Nov 8 '16 at 3:56

This question exists because it has historical significance, but it is not considered a good, on-topic question for this site, so please do not use it as evidence that you can ask similar questions here. This question and its answers are frozen and cannot be changed. More info: help center.

Read more about locked posts here.

migrated from stackoverflow.com May 1 '11 at 21:42

This question came from our site for professional and enthusiast programmers.

2
votes
\$\begingroup\$

I'd always use the second version, since one could use type-hinting. The array style is less transparent.

At least the array style should read like this:

$config = array(
 Class::PARAM_1_INFO =>'abc'
 Class::PARAM_1_SOMETHING =>'dfg'
);

This way, Class is the single point, where the keys get defined.

\$\endgroup\$
2
votes
\$\begingroup\$

if there are many args, use 3rd option. a config class to pass in as an arg. if there are many args, it may be a sign that something is wrong however. generally the fewer arguments, the better.

\$\endgroup\$
0
votes
\$\begingroup\$

Not sure if "work's best" is appropriate, but I know variations of the array approach (including formatted arg strings) are popular on some C projects, because of the issues with varargs and stack corruption.

I quite like the array approach (not all PHP-specific reasons) because:

  • Caller doesn't need to know all the possible args for a given function.
  • Caller doesn't need to guess at sensible defaults
  • Caller automatically gains when recommended defaults change
  • Implementer doesn't need to write lots of variations of a function clogging up the stack with nested calls adding 1 arg.
  • Merging arrays to get defaults is^H^Hcan be fairly painless

With the con:

  • Caller automatically breaks when defaults change

The thing to consider is, without looking into what Class actually does, what is easier to understand in the calling code?

$x = new Class(array('needle'=>'abc','haystack'=>'gagagabcfasfgaf'))

or

$x = new Class('abc','gagagabcfasfgaf')

\$\endgroup\$
  • 2
    \$\begingroup\$ Another pro is "Caller doesn't need to know the order to list the arguments". Any time PHP has a foo_function($needle, $haystack) it seems like they just flip a coin to determine the argument order. \$\endgroup\$ – daybreaker Jun 14 '11 at 21:06
0
votes
\$\begingroup\$

I've had this come up a couple of times recently, and each time ended up realising that the arguments being passed in were actually all attributes of the entity being created. So I've followed the following pattern:

$theObject = new TheClass();
$theObject->setParam1('abc');
$theObject->setParam2('def');
$theObject->doSomething();

Which means that you can force the types of the various attributes, but also validate them further within the set methods, as well as gain a bunch of other benefits such as easier testing etc.

\$\endgroup\$
0
votes
\$\begingroup\$

My advice is to mix both styles: pass the required and important properties directly as parameters, and keep a hash table for optional properties.

For example:

$c = new Class(ImportantRelatedInterface $obj, $options = array(..));

If you really need to set/change some properties after the instantiation, then you can provide some setters, but avoid it to simplify the code if possible. For options, you can provide general setter/getter:

function setOption(..);
function getOption(..);

And even:

function hasOption(..);
\$\endgroup\$

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