2016-08-12 84 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