【问题标题】:PHP7 method_exists Uncaught Error: Function name must be a stringPHP7 method_exists 未捕获错误:函数名必须是字符串
【发布时间】:2015-12-29 07:08:35
【问题描述】:

我收到此错误:

致命错误:未捕获的错误:函数名必须是字符串

对于此代码:

if (function_exists($item['function'])) {
    $item['function']($item, $default);
} elseif (method_exists($this, $item['function'])) {
    $this->$item['function']($item, $default);
}

我知道将代码更改为

if (function_exists($item['function'])) {
    $item['function']($item, $default);
} elseif (method_exists($this,$item['function'])) {
    $this->{$item['function']}($item, $default);
}

解决了这个错误,但我的问题是,这条线是否应该

 $item['function']($item, $default);

也可以转换成

{$item['function']}($item, $default);

还是可以保持原样?

【问题讨论】:

  • 你确定这个项目的功能键已经设置并且是字符串吗?使用前添加检查。

标签: php operator-precedence php-7


【解决方案1】:

这是由于 incompatible changes 在处理间接变量和方法的评估顺序中:

对间接变量、属性和方法的处理的更改

现在将严格按照从左到右的顺序对变量、属性和方法的间接访问进行评估,而不是之前的特殊情况混合。下表显示了评估顺序的变化。

不,您不必更改此行:

$item['function']($item, $default);

因为这里没有进行特殊的求值,所以它只会使用数组元素作为函数名并调用函数。您可以更改它,代码仍然可以正常工作,但这不是必需的。

但正如你已经正确地做的那样,你必须改变:

$this->$item['function']($item, $default);

到:

$this->{$item['function']}($item, $default);
       ↑↑

正如您在table 中看到的那样:

 间接表达式的新旧求值
      表达式 PHP 5 解释 PHP 7 解释
-------------------------------------------------- -----------------------------------------
  $$foo['bar']['baz'] | ${$foo['bar']['baz']} | ($$foo)['bar']['baz']
  $foo->$bar['baz'] | $foo->{$bar['baz']} | ($foo->$bar)['baz']
  $foo->$bar['baz']() | $foo->{$bar['baz']}() | ($foo->$bar)['baz']()
  Foo::$bar['baz']() | Foo::{$bar['baz']}() | (Foo::$bar)['baz']()

PHP 7 将假定您首先要访问一个对象属性,然后您要从该属性访问一个索引,并使用它的值作为方法名来调用一个方法(从左到右的顺序)。

要将变量和索引用作属性名称,您必须使用花括号来表示。

【讨论】:

    【解决方案2】:
    $funName = $item['function'];
    

    并使用(不)数组。

    @Svetlio,不是为了旧版本,而是为了兼容!

    为什么人们会误解这一点?你们都懒得再写一行作业了?

    【讨论】:

    • 在旧的 PHP 版本中是的,但在 7 中肯定不需要。
    猜你喜欢
    • 2020-03-23
    • 1970-01-01
    • 2012-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-26
    • 2011-02-27
    • 1970-01-01
    相关资源
    最近更新 更多