This little beauty lets you use call_user_func_array with an associative array, specifying arguments by name : no more bad signature pain !

function call_user_func_assoc($function, $args = array())
{
    // Does the function exist ?
    try {
        if (strpos($function, '::')) {
            list($class, $method) = explode('::', $function);
            $r = new ReflectionMethod($class, $method);
        } else {
            $r = new ReflectionFunction($function);
        }
    } catch (\ReflectionException $e) {
        throw new \Exception($e->getMessage());
    }

    // Get parameter list
    $params = $r->getParameters();
    $keys = array();
    $missing = array();

    foreach ($params as $param) {
        $keys[] = $param->name;

        if (! array_key_exists($param->name, $args)) {
            try {
                $param->getDefaultValue();
            } catch (\ReflectionException $e) {
                $missing[] = $param->name;
            }
        }
    }

    // If we spotted missing mandatory parameters, we exit
    if ($missingno = count($missing)) {
        throw new \Exception('Missing mandatory parameter'.($missingno > 1 ? 's' : '').': '.implode(', ', $missing));
    }

    // Prepare values
    $values = array();

    foreach ($keys as $key) {
        if (array_key_exists($key, $args)) {
            $values[] = $args[$key];
        }
    }

    return call_user_func_array($function, $values);
}

// Use it !

call_user_func_assoc('myFunction', array('param2' => 'test', 'param3' => 'foo', 'param1' => 'bar'));
call_user_func_assoc('myClass::myMethod', array('param2' => 'foo', 'param1' => 'bar'));