2012-06-08 5 views
4

Когда у закрытий есть параметры (или как работают замыкания с параметрами)? Я знаю, что use() используется для импорт переменных вне анонимной функции, но как насчет параметров (-ов) самого закрытия?Откуда вы знаете, какие параметры/аргументы нужно положить в закрытие?

+2

Вы, безусловно, получаете свои деньги из слова * use *. ';)' –

+0

@JaredFarrish 'use' предназначен для переменной импорта для области анонимной функции. Сокет, подобный '$ fuc = function ($ a, $ b), используется ($ c) {}'. – xdazz

+0

Обратите внимание, что ссылка (как указано выше @xdazz) была неправильной; ссылку [Анонимные функции] (http://www.php.net/manual/en/functions.anonymous.php). –

ответ

3

Пример колпачков с параметрами выделка:

function greeter($greeting) 
{ 
    return function($whom) use ($greeting) { 
    // greeting is the closed over variable 
    return "$greeting $whom"; 
    }; 
} 

$hello_greeter = greeter('hello'); 

echo $hello_greeter('world'); // will print 'hello world'; 

greeter функция возвращает «наполовину реализованы» функцию, которая всегда будет начинаться с тем же приветствием, а затем все, что передается в него (например, человек приветствовать).

+0

Это связано с PHP, а не с Javascript ... –

+0

@JaredFarrish все в порядке, это не так уж и много, хотя :) –

+0

Знаете ли вы это точно? –

2

Если вы используете функцию, которая принимает анонимную функцию как параметр, то проверьте документ функции.

Если функция написана вами, то вы являетесь контроллером, вы ее решаете.

+0

Я больше знаком с закрытием Javascript, но для решения вопроса «почему и когда у вас есть аргументы в закрытии?», Я бы сказал, когда вы либо сопоставляете входящую подпись (например, в обработчике), либо более удобно или полезно передавать в качестве аргументов. Комментарии? –

+0

@JaredFarrish Закрытие PHP - это мусор, отличный от javascript. Когда вы используете переменную снаружи, вам нужно использовать 'use'. – xdazz

+0

Да, я читаю руководство [Using namespaces: Aliasing/Importing] (http://php.net/manual/en/language.namespaces.importing.php), и я понимаю, что мне нужно прочитать об этом. Не то же самое, что и Javascript. –

2

Завершения, переданные функциям PHP, которые должны иметь параметры, подробно описаны в документах. Хорошим примером этого является array_walk(), который используется, чтобы применить функцию обратного вызова для итератора:

$arr = array('a', 'b', 'c'); 
array_walk($arr, function($key, $val) { 
    echo $key . ' => ' . $val . "\n"; 
}); 

в документации, параметры, которые вы должны включить на вызываемая передается array_walk() детализированы в разделе «Параметры». В нем говорится:

Как правило, funcname принимает два параметра. Значение параметра массива является первым, а ключ/индекс вторым.

Часто вы найдете похожие советы по другим функциям в документах PHP. Я был разочарован тем, что документация для array_map() была не такой детализированной, но я помню, что существуют другие функции, которые исключали вызывающие вызовы, которые имели достаточную документацию о параметрах закрытия.


Если вы хотите, чтобы написать свою собственную функцию, которая принимает замыкания (или другие значения, которые вы можете позвонить) и диктует, какие параметры он должен иметь, вы можете использовать typehint callback в PHP 5.3 или callable в PHP 5.4 ,

function gobblesUpCallable(callable $func) { 
    call_user_func($func); // Use this, someone could pass in a callable string or array 
} 

Однако, чтобы определить параметры, вам нужно использовать ReflectionClass или ReflectionFunction означает, что вы, вероятно, отказаться от call_user_func().

+0

Я бы не назвал это закрытием, хотя он ничего не закрывает; скорее, это анонимная функция .. опять же, термин «закрытие» в PHP неоднозначен :) –

+0

@PhpMyCoder 'Только переменные могут передаваться по ссылке – Michelle

+0

@Jack - ссылка на Руководство для [анонимных функций] (http://www.php.net/manual/en/functions.anonymous.php), первый пример идентичен приведенному здесь, за исключением того, что он использует другую функцию. Что не так с этим примером? –

2

use() особенно полезен для функций, для которых требуется функция в качестве параметра. Может потребоваться, чтобы переданная функция принимала только два параметра и что любой дополнительный параметр просто игнорируется. В этом случае используйте «use()» для «импорта» переменной из текущей области в функцию анона.

$myvar = 10; 
$fun = function(&$val, $index) use ($myvar) {$val += $myvar;}; 
$testArray = array(1,2,3); 
array_walk($testArray, $fun); 
var_dump($testArray); // 11, 12, 13 

Примечание: если ваша функция Анон подпись была function(&$val, $index, $myvar) вместо этого, вы получите постоянный warnings при использовании функции Анон с array_walk, потому что дополнительный третий параметр не используется и не определено. Итак, используйте use(), чтобы передать этот дополнительный параметр.

Редактировать: вы также можете передать переменные по ссылке use() ...

$myvar = 10; 
$fun = function(&$val, $index) use (&$myvar) {$myvar = 1; $val += $myvar;}; 
$testArray = array(1,2,3); 
array_walk($testArray, $fun); 
var_dump($testArray); // 2, 3, 4 
echo $myvar; // 1 
Смежные вопросы