dongxi8297
2016-08-12 11:33
浏览 39
已采纳

PHP is_callable with Type Definitions

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!

图片转代码服务由CSDN问答提供 功能建议

一直在搜索PHP文档,这似乎不太可能,但想检查一下。 \ n

假设我有这样的函数:

 类Utils {
静态函数doSomething(Array $ input){
 ... 
} 
  } 
   
 
 

是否可以使用内置的PHP函数,如 is_callable 来检查函数是否存在以及我所拥有的变量是否存在 被函数中的类型定义接受。

所以:

  $ varA = array('a','b',  'c'); 
 $ varB ='some string'; 
 
 $ functionToCall = array('Utils','doSomething'); 
 
is_callable($ functionToCall,$ varA)=>  true; 
is_callable($ functionToCall,$ varB)=>  false; 
   
 
 

当然 is_callable 不能像这样使用。 但是可以在不使用Try Catch的情况下完成吗?

如果不是这样做最好的方法吗?

 试试{\  n Utils :: doSomething(10)
} catch(TypeError $ e){
 // react here 
} 
   
 
 

谢谢!

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

3条回答 默认 最新

  • donglie7778 2016-08-12 12:06
    已采纳

    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

    点赞 打赏 评论
  • dqwolwst50489 2016-08-12 12:12

    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

    点赞 打赏 评论
  • dpf25323 2016-08-12 13:10

    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.
    }
    
    点赞 打赏 评论

相关推荐