1

Been searching the PHP documentation and this doesn't seem possible but wanted to check.

Say I have a function like this:

class Utils {
  static function doSomething( Array $input ){
    ...
  }
}

Is is possible to use a inbuilt PHP function like is_callable to check if both the function exists and if the variable I have will be accepted by the type definition in the function.

So:

$varA = array( 'a', 'b', 'c' );
$varB = 'some string';

$functionToCall = array( 'Utils', 'doSomething' );

is_callable( $functionToCall, $varA ) => true;
is_callable( $functionToCall, $varB ) => false;

Of course is_callable cannot be used like this. But can it be done without using a Try Catch?

If not would this be the best way around it?

try {
  Utils::doSomething( 10 )
} catch (TypeError $e) {
  // react here
}

Thanks!

1
  • In php 7 you can enable strict_types : declare(strict_types=1);... and add the type for every method argument function(string $stringVal); Commented Aug 12, 2016 at 11:44

3 Answers 3

1

You can use a ReflectionClass to access the ReflectionMethod

With the ReflectionMethod you can access the ReflectionParameter and check the type or the class of the parameter

try{
    $method = new ReflectionMethod('Utils', 'doSomething');
    if(!$method->isStatic()){
        $methodOk = false;
    }

    foreach($method->getParameters() as $parameter){
        //Choose the appropriate test
        if($parameter->getType() != $varA || !is_a($varA ,$parameter->getClass()->getName())){
            $methodOk = false;
        }
    }
}
catch(ReflectionException $ex){
    $methodOk = false;
}

Reference : reflectionparameter and reflection

Sign up to request clarification or add additional context in comments.

2 Comments

This is great thanks. In my case there will only be one parameter
This answers the question, but underlying the question is a need that is more commonly addressed by using interfaces.
1

You can use ReflectionFunction

function someFunction(int $param, $param2) {}

$reflectionFunc = new ReflectionFunction('someFunction');
$reflectionParams = $reflectionFunc->getParameters();
$reflectionType1 = $reflectionParams[0]->getType();
$reflectionType2 = $reflectionParams[1]->getType();

echo $reflectionType1;
var_dump($reflectionType2);

Result:

int
null

reference : http://php.net/manual/en/reflectionparameter.gettype.php

Comments

1

It sounds like you're approaching this from the wrong angle.

In your example use-case, it looks like you want to test that the Utils::doSomething() method both exists and accepts the parameters you're expecting to receive.

The typical way of doing this is using an interface.

In your example, you would have an interface like this:

interface utilsInterface
{
    public static function doSomething(Array $input);
}

Your Utils class could then simply be modified to implement this interface:

class Utils implements utilsInterface
{
     public static function doSomething(Array $input)
     {
          //....
     }
}

Now all you need to do in order to check that the class meets your requirements is to check if it implements the interface:

if (Utils::class instanceof utilsInterface) {
    // now we know that we're safe to call Utils::doSomething() with an array argument.
}

1 Comment

Good ! Indeed, it is a best practice to use interfaces when we check classes that we created !

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.