Передача функции по ссылке в PHP
Можно ли передавать функции по ссылке?
Что-то вроде этого:
function call($func){
$func();
}
function test(){
echo "hello world!";
}
call(test);
Я знаю, что вы могли бы сделать 'test'
, но я этого действительно не хочу, поскольку мне нужно передать функцию по ссылке.
Это единственный способ сделать это через анонимные функции?
Уточнение: если вы помните из С++, вы можете передать функцию через указатели:
void call(void (*func)(void)){
func();
}
Или в Python:
def call(func):
func()
То, что я пытаюсь выполнить.
Ответы
Ответ 1
За что стоит, как насчет чего-то подобного? (Да, я знаю, что это анонимная функция, о которой упоминалось в сообщении, но я был недоволен множеством ответов, которые вообще не упоминали о закрытии/функциональных объектах, так что это в основном примечание для людей, работающих на этом посту.)
Я не использую PHP, но с использованием закрытия работает в PHP 5.3 (но не PHP 5.2) в качестве показанного здесь. Я не уверен, какие существуют ограничения, если таковые имеются. (Насколько я знаю, закрытие съест ваших детей. Вы были предупреждены.)
function doIt ($fn) {
echo "doIt\n";
return $fn();
}
function doMe () {
echo "doMe\n";
}
// I am using a closure here.
// There may be a more clever way to "get the function-object" representing a given
// named function, but I do not know what it is. Again, I *don't use PHP* :-)
echo doIt(function () { doMe(); });
Счастливое кодирование.
Ответ 2
Проблема с call_user_func()
заключается в том, что вы передаете возвращаемое значение вызываемой функции, а не самой функции.
Я тоже сталкивался с этой проблемой, и вот решение, с которым я столкнулся.
function funcRef($func){
return create_function('', "return call_user_func_array('{$func}', func_get_args());");
}
function foo($a, $b, $c){
return sprintf("A:%s B:%s C:%s", $a, $b, $c);
}
$b = funcRef("foo");
echo $b("hello", "world", 123);
//=> A:hello B:world C:123
демонстрация ideone.com
Ответ 3
function func1(){
echo 'echo1 ';
return 'return1';
}
function func2($func){
echo 'echo2 ' . $func();
}
func2('func1');
Результат:
echo1 echo2 return1
Ответ 4
Нет, функции не являются значениями первого класса в PHP, они не могут быть переданы их литералом имени (это то, о чем вы просите). Даже анонимные функции или функции, созданные с помощью create_function
, передаются ссылкой на объект или строку.
Вы можете передать имя функции как строку, имя объекта-объекта как массив (object, string)
или анонимную функцию как объект. Ни один из этих указателей пропуска или ссылок, они просто передают имя функции. Все эти методы известны как псевдо-тип callback
: http://php.net/callback
Ответ 5
В PHP 5.4.4 (не тестировали более низкие или другие версии), вы можете сделать то, что вы предложили.
Возьмем это как пример:
function test ($func) {
$func('moo');
}
function aFunctionToPass ($str) {
echo $str;
}
test('aFunctionToPass');
script будет эхом "moo", как если бы вы сразу называли "aFunctionToPass".
Ответ 6
Вы можете сказать
$fun = 'test';
call($fun);
Ответ 7
Вместо call(test);
используйте call_user_func('test');
.
Ответ 8
Аналогичная модель этой функции первого класса Javascript:
function add(first, second, callback){
console.log(first+second);
if (callback) callback();
}
function logDone(){
console.log('done');
}
function logDoneAgain(){
console.log('done Again');
}
add(2,3, logDone);
add(3,5, logDoneAgain);
Может быть сделано в PHP (протестировано с 5.5.9-1ubuntu на C9 IDE) следующим образом:
// first class function
$add = function($first, $second, $callback) {
echo "\n\n". $first+$second . "\n\n";
if ($callback) $callback();
};
function logDone(){
echo "\n\n done \n\n";
}
call_user_func_array($add, array(2, 3, logDone));
call_user_func_array($add, array(3, 6, function(){
echo "\n\n done executing an anonymous function!";
}));
Результат: 5 сделанных 9 выполненных анонимных функций!
Ссылка: https://github.com/zenithtekla/unitycloud/commit/873659c46c10c1fe5312f5cde55490490191e168