Named Parameters Not Simple Enough
I recently wrote something using php. I haven’t paid much attention to the language up to this point, as my daily life calls for mostly Java-specific thinking.
To write this Wordpress plugin, I’ve been faced with encapsulating display code into a function call. It got my skin crawling as soon as I started adding the ability to customize what the function actually displayed. The ideal situation for a plugin is that you provide something that requires little to no modification of actual code but rather configuration in the UI. But reliance on a function call to display HTML output is thwarting this goal pretty effectively due to the growing number of parameters in my display function.
As of right now, the function signature is up to 7 parameters.
function display_feeds_by_date( $num_posts = 10,
$category = ‘Friends’,
$date_format = ‘%A %B, %d %Y %I:%M %p %Z’,
$post_navigation = false,
$default_style = true,
$inc_image = true,
$full_content = true)
There are default values for each parameter specified. So this isn’t such an unusable function for a user of the plugin since they could place a call to the function in a page template without any arguments. The call only becomes unwieldy (or less dramatically, inconvenient) when the user wants to change the display output of the function and starts adding arguments. For instance, if someone wants to specify the ‘$full_content’ parameter as false, they must specify the six other parameters before it. This is due to the sequential specification of the parameters. I don’t want to make my plugin user go through all that. Most of them probably have a very small grasp on programming and php.
A google search on ‘function parameters php’ revealed that Wordpress and b2evolution instruct users on specifying sequential parameters in templates as well.
What are my alternatives then? I could use a query style single parameter function that a call to might look like:
display_feeds_by_date
(’category=D00d&num_posts=20&default_style=TRUE’);
That would then require me to parse the string into variables. There’s the option of an associative array parameter also. But this isn’t very straight forward, or readable. In fact, its much more confusing to me than specifying each parameter as if it was discrete, especially if you have to pass a non-simple type such as an array. But this would effectively allow any ordering and number of parameters. Variable argument list functions aren’t an option since this wouldn’t identify which argument was being specified.
I had initially thought that php would obviously support named parameters. This would be a good way to allow users to specify only one or two parameters anywhere on the parameter/argument list and let all others go to their respective defaults. It had also been my assumption, like in other languages that allow for named parameters, that naming would be optional and that the function would interpret nameless parameters as sequential. Such a call to my display function that simply specified no full content might look like:
display_feeds_by_date(full_content => FALSE);
Interestingly, I discovered that this had been talked about recently in a php developers meeting. The conclusion: named-parameters do not keep it simple, stupid. That was basically what the meeting notes said, and I’m not sure of the reasoning. Is verbosity considered not simple? Was the assumption that named parameters would be required? Or that if programmers saw it being used in code they would be confused or assume that named parameters were a requirement of the language? Named parameters seem simple enough to me, and I’ve outlined a real world reason to include the feature. Granted, the display function is monolithic and coarse-grained, but it is a reasonable compromise of working within the Wordpress plugin framework. It is a pattern that will probably occur in other projects, and named parameters can help alleviate the problems the compromise causes. Besides this, I like named parameters in some instances. It seems the debate simply comes down to style and preference. To fully answer these questions though, I should obviously do some emailing.
My preferred path would be to actually use a template engine and skip the display function calls entirely. Template engines process obtained data (model) and allow users to specify various token strings representing the data within HTML. This leads to more customizability in display than a function call can reasonably allow and the editing experience for users is more HTML-like. Granted, php is a templating system of sorts, but exposing users to programming constructs like function calls isn’t desirable, IMHO. Perhaps there will be more on this later.
December 29th, 2005 at 12:01 pm
Hi, I ended up here while googling for “php named parameters”, to see if there was a way to use this feature.
Since there was no “official” way, and alternatives like using associative array and eval(), I decide to write my own :p
Tell me what you think…
http://tinyurl.com/apts7
December 30th, 2005 at 1:40 am
Thanks for the comment Adam!
There’s a way to do what you asked, to mix default and named parameters, with a weirdness like $named->default_var($default_var), but anyway
Works with PHP5 only… I hope your Wordpress is accepting code on comments, because here it goes:
class named { public function clean() { foreach ($this as $key => $value) { unset($this->$key); } } private function __call($method, $arguments) { if (isset($this->$method)) { return $this->$method; } else { return $arguments[0]; } } } $named = new named(); function inputText($name, $maxlength = 5) { global $named; $html = “maxlength($maxlength) . “\” “; $html .= ” />\n”; $named->clean(); return $html; } echo inputText(’input_name’); echo inputText(’input_name’, $named->maxlength = 10); /* Outputs: */Actually that’s a pretty sweet solution considering the circustances
You can define functions with mandatory parameters, default, and optional (using isset($name->$argument) from my previous code).
__call(), from PHP5, does the magic here, otherwise every method needs to be declared on named, like function maxlength()…
December 30th, 2005 at 2:11 am
Oooops… broken HTML… alternative here:
http://tinyurl.com/89v7c
February 8th, 2008 at 12:59 am
sorry if i’m 3 years late.. but still no plans in php6 for named parameters as far as I can see. that is so sad. it would be an absolutely great feature to have.
February 11th, 2008 at 3:04 am
3 years late too.
And like, *argh*. The main reason I use python for as many projects as possible is because it has named parameters.
Compare:
Ship ship=new ship(200,100,50,50,100,150,120,true);
with the hypothetical:
Coordinates position=new Coordinates(x=200, y=100,z=50);
Color color=new Color(red=50, green=100, blue=150);
Ship ship=new ship(position, color, facing_angle=120, alive=true );
Which would you prefer?
November 5th, 2008 at 7:32 pm
The author uvazhuha! Here’s how to write blogs must! Everyone stands to learn, boys!
November 7th, 2008 at 9:45 pm
Here’s my solution.
First, realize that you can easily make an object out of an array:
$oObject = (object) array(’FirstName’ => ‘Volo’, ‘LastName’ => ‘Mike’);
and so you can read and write this:
echo $oObject->LastName;
$oObject->FirstName = ‘Hello’;
Next, you can make your functions accept an object like so:
function MyFunction(& $oObject) {
}
And you can also use ‘return $oObject’ to make a function return an Object with multiple parameters if you want.
So there you have it — named parameters in an couple easy steps. No parsing necessary.