on Mar 23rd, 2008Calling functions with named arguments

Despite my recent interest in F#, I just had to post this nice little code nugget I came up with for the view/action layer of my framework that allows you to call a method (or function) with named arguments in PHP:

<?php
class news_ListView {

    function render ($id, $page = 0, $items_pp = 10,
                     $order_by = 'date', $method = 'desc') {
        echo "
            id: $id,
            page: $page,
            items_pp: $items_pp,
            order_by: $order_by,
            method: $method
        ";
    }

}

function call_with_namedargs ($callback, $args = array()) {
    $params = get_named_args($callback);

    foreach ($args as $arg => $value) {
        $params[$arg] = $value;
    }

    return call_user_func_array($callback, array_values($params));
}

function get_named_args ($callback) {
    if (is_array($callback))
        $function = new ReflectionMethod($callback[0], $callback[1]);
    else
        $function = new ReflectionFunction($callback);

    $params = array();

    foreach ($function->getParameters() as $param) {

        if ($param->isOptional())
            $params[$param->name] = $param->getDefaultValue();
        else
            $params[$param->name] = null;

    }

    return $params;
}

$view = new news_ListView;
call_with_namedargs(array($view, 'render'), array('order_by' => 'name'));

3 Responses to “Calling functions with named arguments”

  1. buckyon 25 Mar 2008 at 6:47 pm

    hmm, how about you just pass an array to begin with, and check inside of your func for array_key_exists. work with the language instead of against it lol!

  2. Fredrik Holmströmon 25 Mar 2008 at 7:18 pm

    Well the first argument that I can come up with is that it the function signature looks a lot cleaner, and the default values are easier to spot then with a $func_args = array_merge($default, $func_args)-call.

    The array_key_exists (or well, personally I would use isset()) approach isn’t viable unless you have complete control over the source of the functions, plus it pollutes the function code with things it shouldn’t have to care about.

  3. […] makes a difference (first parameter, second parameter, etc.). A little while back I saw a really neat implementation of calling functions with named arguments, that I’ve actually extended a bit on my own using […]

Trackback URI | Comments RSS

Leave a Reply