2016-08-12 82 views
1

一直在寻找PHP文档,这似乎不可能,但想检查。PHP is_callable与类型定义

说我有这样的功能:

class Utils { 
    static function 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的情况下完成吗?

如果不是这会是它周围的最佳方式?

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

谢谢!

+0

在php 7中,您可以启用strict_types:declare(strict_types = 1); ...并为每个方法参数函数(string $ stringVal)添加类型; –

回答

1

可以使用ReflectionClass访问ReflectionMethod

随着ReflectionMethod您可以访问ReflectionParameter和检查类型或类参数

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; 
} 

参考的:reflectionparameterreflection

+0

非常感谢。在我的情况下,将只有一个参数 – James

+1

这回答了这个问题,但潜在的问题是更通常使用接口解决的需求。 – Simba

1

您可以使用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); 

结果:

int 
null 

参考:http://php.net/manual/en/reflectionparameter.gettype.php

1

这听起来像你从错误的角度接近这一点。

在您的例子用例,它看起来像你想测试的Utils::doSomething()方法都存在,并接受你希望接收的参数。

这样做是使用接口的典型方式。

在你的榜样,你有一个这样的接口:

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

Utils类可以再简单地进行修改,以实现此接口:

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

现在,所有你需要做的为了检查该类是否符合您的要求,请检查它是否实现了接口:

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

好!事实上,当我们检查我们创建的类时,最好使用接口! – Benito103e