web-dev-qa-db-fra.com

Normes strictes: seules les variables doivent être transmises par référence

$el = array_shift($instance->find(..))

Le code ci-dessus rapporte en quelque sorte l'avertissement de standard strict, mais cela ne va pas:

function get_arr(){
    return array(1,2);
}
$el = array_shift(get_arr());

Alors, quand va-t-il signaler l'avertissement quand même?

81
user198729

Considérons le code suivant:

error_reporting(E_STRICT);
class test {
    function test_arr(&$a) {
        var_dump($a);   
    }
    function get_arr() {
        return array(1,2);  
    }
}

$t= new test;
$t->test_arr($t->get_arr());

Cela générera la sortie suivante:

Strict Standards: Only variables should be passed by reference in `test.php` on line 14
array(2) {
  [0]=>
  int(1)
  [1]=>
  int(2)
}

La raison? La méthode test::get_arr() n'est pas une variable et, en mode strict, un avertissement est généré. Ce comportement est extrêmement non intuitif car la méthode get_arr()retourne une valeur de tableau.

Pour contourner cette erreur en mode strict, changez la signature de la méthode pour qu’elle n’utilise pas de référence:

function test_arr($a) {
    var_dump($a);  
}

Puisque vous ne pouvez pas changer la signature de array_shift, Vous pouvez également utiliser une variable intermédiaire:

$inter= get_arr();
$el= array_shift($inter);
93
leepowers

$instance->find() renvoie la référence à la variable.

Vous obtenez le rapport lorsque vous essayez d'utiliser cette référence en tant qu'argument pour fonctionner, sans le stocker au préalable dans une variable.

Cela aide à prévenir les fuites de mémoire et deviendra probablement une erreur dans les prochaines PHP versions.

Votre deuxième code jetterait une erreur s'il écrivait comme (notez la signature de la fonction & in):

function &get_arr(){
    return array(1,2);
}
$el = array_shift(get_arr());

Donc, une solution rapide (et pas si agréable) serait:

$el = array_shift($tmp = $instance->find(..));

Fondamentalement, vous effectuez d'abord une affectation à une variable temporaire et envoyez la variable en tant qu'argument.

8
Sagi

La cause de l'erreur est l'utilisation de la fonction interne PHP Programmation de structures de données, array_shift () [php.net/end].

La fonction prend un tableau en paramètre. Bien qu'une esperluette soit indiquée dans le prototype de array_shift() dans le manuel ", il n'existe aucune documentation de mise en garde dans la définition étendue de cette fonction, et il n'y a pas non plus d'explication apparente que le paramètre est en fait passé par référence .

C'est peut-être/compris /. Cependant, je ne comprenais pas, alors il m’était difficile de détecter la cause de l’erreur.

Reproduire le code:

function get_arr()
{
 return array(1,2);
}
$array = get_arr();
$el = array_shift($array);
5
Biju B Adoor

Le deuxième extrait ne fonctionne pas non plus et c'est pourquoi. array_shift est une fonction de modification qui modifie son argument. Par conséquent, il s'attend à ce que son paramètre soit une référence et vous ne pouvez pas faire référence à quelque chose qui n'est pas une variable. Voir les explications de Rasmus ici: Standards stricts: seules les variables doivent être passées par référence

3
user187291

Ce code:

$monthly_index = array_shift(unpack('H*', date('m/Y')));

Besoin d'être changé en:

$date_time = date('m/Y');
$unpack = unpack('H*', $date_time);
array_shift($unpack);
3
user6031348