2015-12-29 2 views
14

Je reçois cette erreur:PHP7 method_exists Uncaught Erreur: Nom de la fonction doit être une chaîne

Fatal error: Uncaught Error: Function name must be a string in

Pour ce code:

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

Je sais que la modification du code à

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

Résolu cette erreur, mais ma question est, devrait cette ligne

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

également être converti en

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

ou peut-il être laissé tel quel?

+0

Etes-vous sûr que cette touche de fonction d'élément est définie et que c'est une chaîne? Ajoutez des vérifications avant de l'utiliser. – Svetoslav

Répondre

-1

Et utilisez à la place (sans) tableau.

@Svetlio, pas pour les versions plus anciennes, mais pour compatible!

Pourquoi les gens ont mal compris cela? Vous êtes tous trop paresseux pour écrire une ligne de plus pour l'affectation?

+2

Dans l'ancienne version de PHP oui, mais dans 7 ce n'est pas nécessaire à coup sûr. – Svetoslav

21

Cela est dû à incompatible changes dans l'ordre de-évaluation pour le traitement des variables et des méthodes indirectes:

Changes to the handling of indirect variables, properties, and methods

Indirect access to variables, properties, and methods will now be evaluated strictly in left-to-right order, as opposed to the previous mix of special cases. The table below shows how the order of evaluaiton has changed.

Non, vous ne devez pas changer cette ligne:

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

Parce que il n'y a pas d'évaluation spéciale ici, il utilisera simplement l'élément array comme nom de fonction et appellera la fonction. Vous pouvez le changer, et le code fonctionnera toujours correctement, mais ce n'est pas nécessaire.

Mais comme vous l'avez déjà fait correctement vous devez changer:

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

à:

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

Depuis que vous pouvez voir dans ce table:

     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 sera supposons que vous voulez d'abord accéder à une propriété d'objet, puis vous voulez accéder à un index de cette propriété, et utilise sa valeur comme nom de méthode pour appeler une méthode (ordre de gauche à droite).

Pour utiliser la variable et l'index comme nom de propriété, vous devez utiliser des accolades pour l'indiquer.