February 27, 2013

Check type of optional parameter in PHP

Question by Patt

I am checking the type of optional parameters in PHP like this:

/**
 * Get players in the team using limit and
 * offset.
 *
 *
 * @param TeamInterface $participant
 * @param int $limit
 * @param int $offset
 * @throws InvalidArgumentException
 * @return Players of a team
 */
public function getPlayers(TeamInterface $team, $limit = null, $offset = null)
{
    if (func_num_args() === 2 && !is_int($limit) ){
        throw new InvalidArgumentException(sprintf('"Limit" should be of int type, "%s" given respectively.', gettype($limit)));
    }
    if (func_num_args() === 3 && (!is_int($limit) || !is_int($offset))){
        throw new InvalidArgumentException(sprintf('"Limit" and "Offset" should be of int type, "%s" and "%s" given respectively.', gettype($limit), gettype($offset)));
    }
//.....

}

This works but there are 2 main issues with this:

1/ If I need to check the type of 4/5 optional parameters for the same int type, the code become unnecessarily long. Any ideas how to make this piece of code more maintainable? (Maybe use only one if statement to check the same type of both $limit and $offset)

2/ getPlayers($team, 2, null) throws an exception. Is this ok knowing that the function can actually handle a null value here?

Answer by thatthatisis

You could do a for loop with an array of args. Something like:

$args = func_get_args();
for ($i = 1; $i < 4; $i++) {
    if ($args[$i] !== null and !is_int($args[$i])) {
        throw ...
    }
}

Of course, adjust the for conditions based on your number of arguments that need to be checked.

Or…

$args = func_get_args();
// skip first
array_shift($args);
foreach ($args as $arg) {
    if ($arg !== null and !is_int($arg)) {
        throw ...
    }
}

Answer by Starx

Use switch to code specific functions.

switch(gettype($limit)) {
    case "integer":
        //do other processing
    break;
}

You cannot leave your code vulnerable like that. As for a safe solution to overcome the vulnerabilities. Create a safe list like this.

public function getPlayers(TeamInterface $team, $limit = null, $offset = null) {
    $safelist = array("var1" => "TeamInterface", "var2" => "integer", "var3" => "integer");
    $args = function_get_args();
    $status = true;
    foreach($args as $key => $var) {
        if(gettype($var)!=$safelist["var".$key]) {
             $status = false;
             break;
        }
    }
    if(!$status) break;

    //...........
}

Author: Nabin Nepal (Starx)

Hello, I am Nabin Nepal and you can call me Starx. This is my blog where write about my life and my involvements. I am a Software Developer, A Cyclist and a Realist. I hope you will find my blog interesting. Follow me on Google+

...

Please fill the form - I will response as fast as I can!