2013-10-05 12 views
8

Czy jest jakaś szansa, że ​​mogę wydedukować informacje o typie parametrów zamknięcia PHP? Rozważmy następujący przykład:Deducing Parametry zamknięcia PHP

<?php 

$foo = function(array $args) 
{ 
    echo $args['a'] . ' ' . $args['b']; 
}; 

$bar = function($a, $b) 
{ 
    echo $a . ' ' . $b; 
}; 

$closure = /* some condition */ $foo : $bar; 

if(/* $closure accepts array? */) 
{ 
    call_user_func($closure, ['a' => 5, 'b' => 10]); 
} 
else 
{ 
    call_user_func($closure, 5, 10); 
} 

?> 

Chcę zostawić pewną swobodę dla użytkownika tak, on lub ona mogła zdecydować, który sposób jest lepszy do definiowania zamknięcia, które zostaną zarejestrowane w moim dyspozytora - będzie akceptować parametrów w tablicy asocjacyjnej lub bezpośrednio jako parametry zamknięcia. Tak więc, dyspozytor musi wydedukować parametry przekazanego zamknięcia, aby określić, w jaki sposób powinien wywołać to zamknięcie. Jakieś pomysły?

Odpowiedz

10

Zastosowanie reflection, jeśli trzeba podejmować decyzje, na podstawie struktury kodu. W twoim przypadku ReflectionFunction i ReflectionParameter są twoimi przyjaciółmi.

<?php 
header('Content-Type: text/plain; charset=utf-8'); 

$func = function($a, $b){ echo implode(' ', func_get_args()); }; 

$closure = &$func; 
$reflection = new ReflectionFunction($closure); 
$arguments = $reflection->getParameters(); 

if($arguments && $arguments[0]->isArray()){ 
    echo 'Giving array. Result: '; 
    call_user_func($closure, ['a' => 5, 'b' => 10]); 
} else { 
    echo 'Giving individuals. Result: '; 
    call_user_func($closure, 5, 10); 
} 
?> 

wyjściowa:

Giving individuals. Result: 5 10 

Zmiana definicji do testu:

$func = function(array $a){ echo implode(' ', $a); }; 

wyjściowa:

Giving array. Result: 5 10 
+0

Właśnie tego szukałem! Dziękuję, nie wiedziałem, że PHP ma odbicie :) –

+0

@ nyan-cat Pozdrawiam. Miło, że mogłem pomóc. – BlitZ

2

Znacznie łatwiej byłoby by Twoja funkcja była w stanie akceptować różne typy danych wejściowych.

Na przykład, w tym przypadku:

$foo = function() { 
    $args = func_get_args(); 
    if(is_array($args[0])) $args = $args[0]; 
    echo $args[0]." ".$args[1]; 
} 
+1

Tak, wiem, ale to uczyni rzeczy niewygodne dla moich użytkowników którzy piszą swoje Zamknięcia. Moim celem jest pozbycie się wszelkiego rodzaju wymagań, aby umożliwić użytkownikowi wdrożenie jego Zamknięcia bez specjalnej wiedzy o sposobie jego realizacji. –