2012-10-25 2 views
13

참고 :이 quesiton을 작성한 덕분에 이미 새로운 언어 기능을 사용하는 데 열성적이었습니다. 훨씬 깨끗한 솔루션은 전략 패턴을 대신 사용하고있었습니다 ... 여전히이 문제에 대해 적절한 방법이 있는지 궁금합니다.런타임에서 호출 할 수있는 매개 변수의 수를 얻는 방법은 무엇입니까?

TL : 모든 종류의 호출 가능 코드를 수동으로 typechecking하지 않고도 PHP의 범용 Callable을 반영 할 수 있습니까?

PHP 5.4에서는 새로운 유형 힌트 인 callable이 있습니다. 이것은 많은 재미로 보인다.

<?php 
    public function setCredentialTreatment(callable $credentialTreatment) { 
     // Verify $credentialTreatment can be used (ie: accepts 2 params) 
     ... magic here ... 
    } 
?> 

지금까지 생각의 내 라인이 호출에 형식 일련의 검사를 수행하고, 그 어떤 반사에서 추론했다 * 클래스가 사용하는 : 나는 다음을 통해이 사용을 거라고 생각 :

지금, 나에게 이것은 지나치게 복잡하다고 느낍니다. 내가 여기서하려고하는 것을 달성하기 위해 어떤 종류의 지름길을 놓치고 있습니까? 모든 통찰력을 환영합니다 :)

+0

: 그것을 사용하는 방법에 대한

테스트 및 제안 사항은 아래에 포함되어 난이 도움이 되었으면 좋겠 :

function getNrOfParams($callable) { $CReflection = is_array($callable) ? new ReflectionMethod($callable[0], $callable[1]) : new ReflectionFunction($callable); return $CReflection->getNumberOfParameters(); } 

테스트 및 전체에서의 결과 모든 호출 가능 객체에 대한 Reflection 객체를 가져 오는 도우미 함수를 작성했습니다. 이 함수의 코드는 당신과 거의 같습니다. – Benjamin

+0

이 작업을 계속한다면 나는 몰라. 그러나 당신은 아마도 더 쉬운 패키지 차이점에 도움이되는 자신 만의 CallableReflection을 만들 것을 고려해 보았는가? – hakre

+0

결국이 경로를 더 추구하지는 않았지만 재사용 가능한 CallableReflection을 만드는 것이 올바른 방향으로 나아가는 것처럼 보입니다. 어떤 시점에서 필자는 PHP의 Reflection 모듈이 이러한 라인을 따라 무언가를 제공 할 것으로 기대합니다. – kander

답변

2

나는 call_user_func()과 매우 유사한 단축 버전을 만들었고 콜백/호출 용 PHP 매뉴얼의 모든 다른 유형에 대해 테스트했다. 이렇게하면 거의 모든 곳에서 사용할 수 있습니다. call_user_func()는 객체만을 가져 가지 않으며 콜백 만 처리하기 때문에이 함수가 필요하다는 것을 나에게 알리지 못했다. 나는 비슷한 문제로 실행

<?php 
class Smart 
{ 
    public function __invoke($name) 
    { 

    } 

    public function my_callable($one, $two, $three) 
    { 

    } 

    public static function myCallableMethod($one, $two) 
    { 

    } 

    public static function who() 
    { 
      echo "smart the parent class"; 
    } 
} 

class Smarter extends Smart 
{ 
    public static function who() 
    { 
     echo "smarter"; 
    } 
} 

function my_ca($one) 
{ 

} 

function getNrOfParams($callable) 
{ 
    $CReflection = is_array($callable) ? new ReflectionMethod($callable[0], $callable[1]) : new ReflectionFunction($callable); 
    return $CReflection->getNumberOfParameters(); 
} 
// Test 1 Callable Function 
echo "Test 1 - Callable function:" . getNrOfParams('my_ca'); 

// Test 2 Static method 
echo " Test 2 - Static class method:" . getNrOfParams(array('Smart', 'myCallableMethod')); 

// Test 3 Object method 
$smart = new Smart(); 
echo " Test 3 - Object method:" . getNrOfParams(array($smart, 'my_callable')); 

// Test 4 Static method call (As of PHP 5.2.3) 
//echo " Test 4 - Static class method call:" . getNrOfParams('Smart::myCallableMethod'); 
// Calling a static method this way does not work in ReflectionFunction. 
// However, Test 2 provides a solution. 

// Test 5 Relative static method (As of PHP 5.3.0) 
//echo " Test 5 - Relative static class method:" . getNrOfParams(array('Smarter', 'parent::who')); 
// Calling a relative static method doesn't work either. ReflectionMethod lacks support. 
// All other tests work. 

// Tesy 6 __invoke 
echo " Test 6 - __invoke:" . getNrOfParams(array($smart, '__invoke')); 

// Test 7 Closure 
$closure = function($one, $two, $three) 
{ 
    // Magic 
}; 
echo " Test 7 - Closure:" . getNrOfParams($closure); 
+0

굉장! 내가 찾던 모든 것을 다 다루었 기 때문에이 대답을 수락했다. 훌륭한 직업 :) – kander

0

인수를 사용하여 배열을 전달할 수 있으며 배열 값을 계산하여 콜백 함수에 전달 된 인수를 알 수 있습니다.

관련 문제