Arash DaneshAraste
Arash DaneshAraste

Reputation: 363

How to write a function with an optional argument and variable length arguments?

I want to implement a method inside a class like this:

class Query {
    public function orderBy($dir="asc", ...$fields){}
}

Where $dir is a default argument and $field is a variable-length argument using (...) token.

The problem is that variable-length argument must be declared at the end, and when I do this, the developer can’t skip the first argument to its default. How can I fix this?

Note that I don’t want to use func_get_args() because I want the developer to have some type hints.

Upvotes: 3

Views: 228

Answers (2)

BeNice
BeNice

Reputation: 2305

What I wanted to do was:

function tableHead($id=NULL, $class=NULL, ...$columnsHeads)

the "logical" function call when the first two arguments were not wanted to me was:

tableHead( , , "Dogs","Cars","Sausages");

Sadly PHP does not let you use a , as an empty default value. I get round this by sticking a NULL, NULL, as the first 2 arguments. Not ideal but will do for now!

(I am sure I have used empty , in some language 20 years ago to send an empty value - anyone know? - Or is it just wishful thinking?)

My SOLUTION (haha) is:

tableHead(NULL, NULL, "dogs","cars", "sausages");

Not ideal but it works. In normal usage the function will be called with id and class specified by variables. Personally I do not see anything unholy about combining variadic and optional arguments ... but you do have to be a bit careful!

Upvotes: 0

yivi
yivi

Reputation: 47434

This is simply not doable. PHP does not support this, and it doesn't make a lot of sense that it would. The only way this could work is by having named arguments, as in some other languages, making argument order irrelevant.

Furthermore, your requirment of using a variadic argument there is artificial, and not very useful. Just use an array and an optional order argument.

E.g.:

function orderBy(array $columns, string $order = 'asc') {
    // do your thing
}

Neater, simpler to understand to the method users, and complies with the language syntax.

If you want it to look "similar" to a variadic function, just call the method using a syntax like this:

orderBy(["column1", "column5"]);

orderBy(["column2"], 'desc');

Upvotes: 1

Related Questions