PHP7 method_exists Uncaught Error: имя функции должно быть строкой

Я получаю эту ошибку:

Неустранимая ошибка: Uncaught Error: имя функции должно быть строкой в

Для этого кода:

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

или можно оставить как есть?


person backups    schedule 29.12.2015    source источник
comment
Вы уверены, что эта функциональная клавиша элемента установлена ​​и это строка? Добавьте проверки перед использованием.   -  person Svetoslav    schedule 29.12.2015


Ответы (2)


Это связано с несовместимыми изменениями в порядке оценки для обработки. косвенные переменные и методы:

Изменения в обработке косвенных переменных, свойств и методов

Косвенный доступ к переменным, свойствам и методам теперь будет оцениваться строго слева направо, в отличие от предыдущего сочетания особых случаев. В таблице ниже показано, как изменился порядок оценки.

Нет, вам не нужно менять эту строку:

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

Поскольку здесь не происходит специальной оценки, он просто использует элемент массива в качестве имени функции и вызывает функцию. Вы можете изменить его, и код все равно будет работать правильно, но это не обязательно.

Но, как вы уже сделали правильно, вам нужно изменить:

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

to:

$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 предполагает, что вы сначала хотите получить доступ к свойству объекта, а затем вы хотите получить доступ к индексу из этого свойства и использовать его значение в качестве имени метода для вызова метода (слева направо).

Чтобы использовать переменную и индекс в качестве имени свойства, вы должны указать это с помощью фигурных скобок.

person Rizier123    schedule 29.12.2015

$funName = $item['function'];

И использовать вместо (без) массив.

@Svetlio, не для старых версий, а для совместимых!

Почему люди неправильно это понимают? Вам все лень написать еще одну строчку для задания?

person Deep    schedule 29.12.2015
comment
В более старой версии PHP да, но в 7 это точно не требуется. - person Svetoslav; 29.12.2015