PHP7 method_exists未捕获错误:函数名称必须是字符串

2022-08-30 23:20:14

我收到此错误:

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

对于此代码:

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);

还是可以保持原样?


答案 1

这是由于处理间接变量和方法的评估顺序发生不兼容更改

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

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

不,您不必更改此行:

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

由于此处没有进行特殊评估,因此它只会使用数组元素作为函数名称并调用函数。您可以更改它,代码仍将正常工作,但这不是必需的。

但是,正如您已经正确执行的那样,您必须更改:

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

自:

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

因为正如您在此中看到的:

                    Old and new evaluation of indirect expressions
      Expression            PHP 5 interpretation         PHP 7 interpretation
-------------------------------------------------------------------------------
  $$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,不是旧版本,而是兼容!

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


推荐