【问题标题】:PHP - is there a way to save an already defind function in a variable?PHP - 有没有办法将已定义的函数保存在变量中?
【发布时间】:2014-06-11 08:13:46
【问题描述】:

我对谷歌无法真正帮助我的事情感兴趣...

我知道可以使用匿名函数并将函数存储在 PHP 中的变量中

$function = function myFoo() { echo "bar"; }

并使用变量调用它:$function();

到目前为止一切都很好,但是如果我在某处声明了一个函数或方法但​​在初始化时没有保存呢?

我有一个函数需要一个可调用的,当然call_user_func() 可以在这里帮助我,但是我需要在我的回调处理程序中传递方法名称,我认为这是非常不安全的,因为在我添加回调的那一刻我不能说它是否真的是一个函数并且在我存储它时存在。

这就是为什么我想实现以下场景:

这个函数:

function anyFunction() {
    echo "doWhatever...!";
}

应该稍后保存在变量中:

$myOtherFunction = get_registered_func("anyFunction"); 

我知道get_registered_func() 不存在,但我想知道这是否可能!

有了这个,我现在可以拥有另一个功能

function setCallback(callable $theCallbackFunction) { }

并像这样使用它:

setCallback($myOtherFunction);

这将有一个很大的优势,即当参数没有函数或不存在时抛出异常/致命。

那么简而言之,有没有办法将之前定义的、已经存在的函数或方法存储在变量中?

【问题讨论】:

  • 当然我知道它可以做我想做的事,但这是一种寻找更好实施方式的研究。当它不可能时,我当然必须坚持下去。 :P
  • 您的第一个定义不是有效的 PHP 代码(因为匿名函数不能有名称)。您的问题归结为可调用的内容 - 如果指向有效的函数名称,则字符串是可调用的。使用is_callable() 使其“安全”

标签: php function variables callback store


【解决方案1】:

我看不出为什么这不应该是可能的,除了没有一个 PHP 函数可以做到这一点。匿名函数语法是 PHP 中新引入的,如果它仍然有点粗糙,我不会感到惊讶。

你总是可以包装它:

function wrap_function ($callback) {
    if (is_callable($callback) === false) {
        throw new Exception("nope");
    }
    return function () {
        call_user_func($callback, func_get_args());
    }
}
$foo = new Foo();
$ref = wrap_function(array($foo, "bar"));

【讨论】:

  • 这根本不能确保 $callback 实际上是可调用的,这正是 OP 正在寻找的。​​span>
  • PHP 从不保证某些东西是否可调用。如果它坏了它就坏了。
【解决方案2】:

PHP's callable meta type可以是:

  • 一个字符串
  • 一个数组
  • 匿名函数

只有后一种在某种程度上是“类型安全的”,即如果你得到一个匿名函数,你就知道它是你可以调用的。其他两个选项只是形式化的非正式标准(如果有意义的话),由一些接受回调的函数支持;它们实际上不是 PHP 类型系统中的 type。因此,基本上无法保证您可以对它们做出任何保证。

您只能通过检查您获得的callable 是否可以在执行它们之前使用is_callable 调用来解决此问题。例如,您可以将其包装到您自己的类中,以实际创建一个真正的可调用类型。

【讨论】:

  • 一个字符串?好吧,我试过了,但收到了另一个结果:可捕获的致命错误:传递给 myFunctionTest() 的参数 1 必须是可调用的,在第 2 行的 path/to/my/file.php 中没有给出
  • 说什么? "none given" 显然意味着您没有传递参数。 callable 作为类型提示接受字符串(注意 callable 作为实际类型提示仅在 5.4 之后可用):3v4l.org/7OBZj
  • 是的,我会使用 is_callable,谢谢大家,但这似乎是唯一也是最好的解决方案。
【解决方案3】:

不是一个好方法,但也许这对你有帮助:

function foo($a) {
    echo $a;
}

$callFoo = 'foo';

$callFoo('Hello World!'); // prints Hello

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-16
    • 2014-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多