Quick one:
Is there any way to enforce types for variadic functions in PHP? I’m assuming not, however maybe I’ve missed something.
As of now, I’m just forcing a single required argument of the needed type, and iterating to check the rest.
public function myFunction(MyClass $object){
foreach(func_get_args() as $object){
if(!($object instanceof MyClass)){
// throw exception or something
}
$this->_objects[] = $object;
}
}
Any better solutions?
Purpose:
A container object that acts as an iterated list of the child objects, with some utility functions. calling it with a variadic constructor would be something like this:
// returned directly from include
return new MyParent(
new MyChild($params),
new MyChild($params),
new MyChild($params)
);
The other option could be an addChild method chain:
$parent = new MyParent;
return $parent
->addChild(new MyChild($params))
->addChild(new MyChild($params))
->addChild(new MyChild($params));
The children take several arguments to their constructor as well, so I’m trying to balance between legibility and processing expense.
Well I would say it depends on the number of arguments 🙂 There is nothing like a list (all arguments 1-n as MyClass [before PHP 5.6, for PHP 5.6+ see Variadic functions]), it’s more that you need to write each argument (as in your question) and it’s allowed to send more but only the ones defined will be checked.
However you can define more and make them optional. Hence why I just wrote it depends on the number of arguments:
With such an example, PHP would have thrown the exception already when the argument is not NULL and not MyClass (Passing NULL if given as default value, is possible to pass as well). Optional parameter should not be part of the return value of
func_get_args(). I mean, if you don’t pass the third argument (here named$object3) it won’t appear in the array returned byfunc_get_args().No idea if that is more practicable for you than your the code in the question.
If you face more such situations in your code, you can create some sort of helper to validate the input of function calls and delegate to throw the exceptions with nice error message from the helper. That will prevent duplicate code and will give more comfort in development as you can make the exception notices nicer as you write them for multiple cases.
According to your new feedback, if you want first of all the interpreter let the work of checking, a little iteration and the addMember function would do it:
Instantiating the object with a wrong type of object in any of the list will prevent the Collection to be instantiated.
you can then just do this: