2009-03-09 18 views
41

Potrzebuję przekazać funkcję jako parametr do innej funkcji, a następnie wywołać przekazaną funkcję z funkcji ... To chyba łatwiej mi wyjaśnić w kodzie .. Zasadniczo chcę zrobić coś takiego:Funkcja przejścia przez PHP jako parametr, a następnie wywołanie funkcji?

function ($functionToBeCalled) 
{ 
    call($functionToBeCalled,additional_params); 
} 

Czy istnieje sposób, aby to zrobić .. Używam PHP 4.3.9

Dzięki!

+0

To brzmi jak przyrządzanie curry. –

Odpowiedz

77

Myślę, że szukasz call_user_func.

Przykład z podręcznika PHP:

<?php 
function barber($type) { 
    echo "You wanted a $type haircut, no problem"; 
} 
call_user_func('barber', "mushroom"); 
call_user_func('barber', "shave"); 
?> 
+48

Reguły fryzury Grzyb! – Alex

+5

i co się dzieje, gdy fryzjer należy do innej klasy? inna przestrzeń nazw? – abbood

25
function foo($function) { 
    $function(" World"); 
} 
function bar($params) { 
    echo "Hello".$params; 
} 

$variable = 'bar'; 
foo($variable); 

Dodatkowo, można zrobić to w ten sposób. Zobacz variable functions.

+2

Myślę, że trochę tam przeskakujesz. IIRC, ten kod nie zacznie działać, dopóki nie pojawi się PHP 5.3. –

+1

"pasek" musi być cytowany, ponieważ jest ciągiem znaków. – Gumbo

+1

Funkcje zmiennych @ Jeeremy DeGroot zostały na zawsze – Greg

22

W php jest to bardzo proste.

<?php 

function here() { 
    print 'here'; 
} 


function dynamo($name) { 
$name(); 
} 

//Will work 
dynamo('here'); 
//Will fail 
dynamo('not_here'); 
10

Można również użyć call_user_func_array(). Umożliwia przekazanie tablicy parametrów jako drugiego parametru, dzięki czemu nie musisz dokładnie wiedzieć, ile zmiennych przekazujesz.

7

Znam oryginalne pytanie na temat PHP 4.3, ale teraz jest kilka lat później i chciałem po prostu poprzeć mój ulubiony sposób na zrobienie tego w PHP 5.3 lub nowszym.

PHP 5.3+ zawiera teraz obsługę anonymous functions (closures), więc możesz używać standardowych technik programowania funkcjonalnego, jak w językach takich jak JavaScript i Ruby (z kilkoma zastrzeżeniami). Przepisanie call_user_func powyższy przykład w stylu „zamknięcia” wyglądałby następująco, co znajdę bardziej eleganckie:

$barber = function($type) { 
    echo "You wanted a $type haircut, no problem\n"; 
}; 

$barber('mushroom'); 
$barber('shave'); 

Oczywiście, to nie kupuje Ci dużo w tym przykładzie - moc i elastyczność przychodzi kiedy przechodzą one anonimowe funkcje do innych funkcji (jak w pytaniu oryginalnym). Więc można zrobić coś takiego:

$barber_cost = function($quantity) { 
    return $quantity * 15; 
}; 

$candy_shop_cost = function($quantity) { 
    return $quantity * 4.50; // It's Moonstruck chocolate, ok? 
}; 

function get_cost($cost_fn, $quantity) { 
    return $cost_fn($quantity); 
} 

echo '3 haircuts cost $' . get_cost($barber_cost, 3) . "\n"; 
echo '6 candies cost $' . get_cost($candy_shop_cost, 6) . "\n"; 

Można to zrobić z call_user_func, oczywiście, ale uważam, że ta składnia znacznie jaśniejsze, zwłaszcza gdy nazw i zmienne składowe angażować.

Jedno zastrzeżenie: Będę pierwszym, który przyzna, że ​​nie wiem dokładnie, co się tutaj dzieje, ale nie zawsze można nazwać zamknięciem zawartym w zmiennej członkowskiej lub statycznej, a być może w niektórych innych przypadkach. Ale ponowne przypisanie go do zmiennej lokalnej pozwoli na jej wywołanie. Tak więc, na przykład, to daje błąd:

$some_value = \SomeNamespace\SomeClass::$closure($arg1, $arg2); 

Ale to proste obejście rozwiązuje problem:

$the_closure = \SomeNamespace\SomeClass::$closure; 
$some_value = $the_closure($arg1, $arg2); 
4

Jeśli potrzebujesz funkcji przekazać parametr jako parametr, można spróbować to:

function foo ($param1){ 
    return $param1; 
} 

function bar ($foo_function, $foo_param){ 
    echo $foo_function($foo_param); 
} 

//call function bar 
bar('foo', 'Hi there'); //this will print: 'Hi there' 

phpfiddle example

Mam nadzieję, że będzie pomocny ...

+0

Czy to naprawdę działa? Wszelkie referencje? –

+0

Tak, to zadziała .. Zrobiłem to sam, bez odniesienia ... –

+0

Czy ktoś może potwierdzić? –

Powiązane problemy