2017-07-06 4 views
-1

je le code suivant:PHP 7: Quel est le problème de passer une non-variable par référence et pourquoi un AVIS si la fonction est passée, mais une erreur FATALE si le tableau est passé?

$family = cis_resempty(wp_get_post_terms($post->ID,'family'),0); 

Je reçois l'erreur suivante:

Notice: Only variables should be passed by reference in C:\xampp.....xxx.php on line 18

Si je fais ce qui suit:

$family = cis_resempty(array('a'),0); 

-je obtenir même

Fatal error: Only variables can be passed by reference in C:\xampp...xxx.php on line 16

La fonction est cis_resempty comme celui-ci (mais son d'une bibliothèque):

function cis_resempty(&$var,$key) { ... } 

Trouvé que si je retire le signe de référence & dans la liste des paramètres de cis_resempty il n'y a aucune erreur.

Si je fais ceci:

$family = @cis_resempty(wp_get_post_terms($post->ID,'family'),0); 

Il n'y a aucun avis et tout fonctionne - mais Netbeans dit:

Misuse of the error control operator

Mais si je fais ceci:

$family = @cis_resempty(array('a'),0); 

La fatale erreur continue d'exister.

Pourquoi est-ce que je peux passer une fonction par référence et supprimer la notification avec l'opérateur de contrôle d'erreur mais si je passe un tableau j'obtiens une erreur fatale?

Pourquoi est-il mauvais de passer une variable non par référence?

Répondre

2

Le terme "non variable" fait référence à une variable que le programmeur ne peut pas faire référence à par nom. Ce sont des variables temporaires allouées par l'exécuteur à l'exécution: Le résultat d'un appel de fonction ou d'une autre expression, qui n'est pas affecté à une variable nommée.Passer un élément par référence n'a de sens que si la variable transmise par référence est nommée, de sorte que lorsque l'appel est terminé, l'appelant peut accéder à ce qui a été transmis par référence à l'appelé. Lorsque PHP rencontre un appel de fonction au moment de la compilation, l'espace pour le résultat de l'appel de fonction et les paramètres de l'appel de fonction sont réservés, puis alloués à l'exécution par rapport à la trame d'exécution. Lorsque vous passez le résultat d'un appel de fonction par référence, l'exécuteur est capable de forcer le comportement par référence pour la variable, car il y a de l'espace sur le tas et il peut simplement ignorer que la variable n'a pas de nom ... En général, cela a du sens, mais cela reste pour des raisons de rétrocompatibilité.

Lorsque PHP rencontre un littéral (tableau) au moment de la compilation, il alloue l'espace pour les données relatives au tableau op (fonction) lui-même. A cause de cette différence, forcer le comportement par référence des littéraux serait dangereux et provoquerait un comportement très inattendu: Pensez à ce qui se passerait lorsque la fonction est ré-entrée, simultanément ou autrement.

3

REMARQUE: jamais utilisez '@' pour supprimer.

Why can I pass a function by reference and suppress the notice with the error control operator but if I pass an array I get a fatal error?

Lire ici Passing by Reference première note:

There is no reference sign on a function call - only on function definitions. Function definitions alone are enough to correctly pass the argument by reference. As of PHP 5.3.0, you will get a warning saying that "call-time pass-by-reference" is deprecated when you use & in foo(&$a);. And as of PHP 5.4.0, call-time pass-by-reference was removed, so using it will raise a fatal error.

PHP ne "support" pas depuis 5.4.0 => vous obtenez E_FATAL dans tous les cas. Avec @ ou sans @. Pour la fonction - vous obtenez E_STRICT. D'accord. Ensuite, lire à propos de @ travailler plus ici Error Control Operators. Encore une fois, la première note:

Note: The @-operator works only on expressions. A simple rule of thumb is: if you can take the value of something, you can prepend the @ operator to it. For instance, you can prepend it to variables, function and include calls, constants, and so forth. You cannot prepend it to function or class definitions, or conditional structures such as if and foreach, and so forth.

Essayez ce code (il éclairera):

error_reporting(E_ALL); 

$arr = [1,2,3,4,5,]; 

$a_closure = function(){ 
    return [1,2,3,4,5]; 
}; 

function a(){ 
    return [1,2,3,4,5]; 
} 

function ref_func(&$input){ 
    foreach($input as &$in){ 
     $in++; 
    } 
} 

ref_func($a);   // @ref_func($a); 
ref_func(a());   // @ref_func($a()); 
ref_func($a_closure); // @ref_func($a_closure); 
// Fatals in both 
ref_func([1,2,3,4,5]); // @ref_func([1,2,3,4,5]);