繁体   English   中英

在 PHP 中通过引用传递一个 function

[英]Pass a function by reference in PHP

是否可以通过引用传递函数?

是这样的:

function call($func){
    $func();
}

function test(){
    echo "hello world!";
}

call(test);

我知道你可以做'test' ,但我真的不想那样,因为我需要通过引用传递 function 。

是通过匿名函数这样做的唯一方法吗?

澄清:如果你回忆起 C++,你可以通过指针传递 function:

void call(void (*func)(void)){
    func();
}

或者在 Python:

def call(func):
    func()

这就是我想要完成的。

对于它的价值,试一试这样的东西怎么样? (是的,我知道这是一个在帖子提到匿名函数,但我对大量的回复感到不满,这些回复根本没有提到闭包/函数对象,所以这主要是给浏览这篇文章的人的一个说明。)

我不使用 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(); });

快乐编码。

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 演示

function func1(){
    echo 'echo1 ';
    return 'return1';
}

function func2($func){
    echo 'echo2 ' . $func();
}

func2('func1');

结果:

echo1 echo2 return1

不,函数不是 PHP 中的一等值,它们不能通过它们的名称文字传递(这就是你所要求的)。 甚至匿名函数或通过create_function创建的函数也由对象或字符串引用传递。

您可以将函数的名称作为字符串传递,将对象方法的名称作为(object, string)数组传递或将匿名函数作为对象传递。 这些都没有传递指针或引用,它们只是传递函数的名称。 所有这些方法都称为callback伪类型: http : //php.net/callback

在 PHP 5.4.4(未测试过更低版本或其他版本)中,您可以完全按照您的建议进行操作。

以此为例:

function test ($func) {
    $func('moo');
}

function aFunctionToPass ($str) {
    echo $str;
}

test('aFunctionToPass');

该脚本将回显“moo”,就像您直接调用“aFunctionToPass”一样。

这个 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 中完成(在 C9 IDE 上使用 5.5.9-1ubuntu 测试):

// 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

您可以通过在声明时将函数分配给局部变量来创建引用:

$test = function() {
    echo "hello world!";
};

function call($func){
    $func();
}

call($test);

你可以说

$fun = 'test'; 
call($fun); 

而不是call(test); , 使用call_user_func('test'); .

从 PHP 8.1 开始,您可以使用First-class callables

call(test(...));

你甚至可以使用方法:

call($obj->test(...));

就这么简单。

似乎有点不清楚为什么要通过引用传递函数? 通常只有当引用的数据需要(可能)由 function 修改时,才会通过引用传递。

由于 PHP 使用 arrays 或字符串来引用函数,您可以通过引用传递数组或字符串,这将允许修改 function 引用。

例如,你可以做类似的事情

<?php
$mysort = function($a, b) { return ($a < $b) ? 1 : -1; };
adjust_sort_from_config($mysort); // modifies $mysort
do_something_with_data($mysort);

在哪里

<?php
function load_my_configuration(&$fun)
{
  $sort_memory = new ...;
  ...
  $fun = [$sort_memory, "customSort"];
  // or simply
  $fun = function($a, b) { return (rand(1,10) < 4 ? 1 : -1; };
}

这是有效的,因为有三种方法可以通过变量在 PHP 中引用 function:

  • $name – 字符串 $name 包含应该调用的全局命名空间中的 function 的名称
  • array($object, $name) – 引用名为 object $object 的字符串 $name 的方法。
  • array($class, $name) – 引用 static function string $name of class $class。

如果我没记错的话,这些构造指向的方法和 static 函数必须是公开的。 考虑到足够新的 PHP 版本,“ First-class callable syntax ”应该改进这个限制,但它似乎只是Closure::fromCallable()周围的一些语法糖。

匿名函数在幕后的工作方式相同。 您只是在任何地方都看不到这些函数的文字随机名称,但对匿名 function 的引用也只是一个变量的值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM