Problème de passage par référence avec PHP 5.3.1

Ok, c'est un problème bizarre, alors veuillez supporter avec moi comme je l'explique.

Nous avons mis à jour nos serveurs de développement de PHP 5.2.5 à 5.3.1.

En chargeant notre code après le commutateur, nous commençons à obtenir des erreurs comme:

Warning: Parameter 2 to mysqli_stmt::bind_param() expected to be a reference, value given in /home/spot/trunk/system/core/Database.class.php on line 105

La ligne mentionnée (105) est la suivante:

call_user_func_array(Array($stmt, 'bind_param'), $passArray);

, Nous avons changé la ligne à la suivante:

call_user_func_array(Array($stmt, 'bind_param'), &$passArray);

À ce stade (parce que allow_call_time_pass_reference) est désactivé, php lance ceci:

Deprecated: Call-time pass-by-reference has been deprecated in /home/spot/trunk/system/core/Database.class.php on line 105

Après avoir essayé de résoudre ce problème pendant un certain temps, je me suis cassé et allow_call_time_pass_reference pour sur.

Qui s'est débarrassé de l'avertissement Deprecated, mais maintenant l'avertissement Warning: Parameter 2 to mysqli_stmt::bind_param() expected to be a reference est lancé à chaque fois, avec ou sans le référencement.

Je n'ai aucune idée de comment résoudre ce problème. Si la méthode cible était la mienne, je référencerais simplement les variables entrantes dans la déclaration func, mais c'est une méthode (relativement) native (mysqli).

Quelqu'un a-t-il vécu cela? Comment puis-je obtenir autour d'elle?

Merci.

32
demandé sur hakre 2010-01-12 03:14:16

9 réponses

Vous Passez un tableau d'éléments ($passArray). Le deuxième élément à l'intérieur de le tableau passé doit être une référence, car c'est vraiment la liste des éléments que vous passez à la fonction.

16
répondu Zak 2014-02-10 19:41:39

Je viens de rencontrer ce même problème, en appelant bind_param via call_user_func_array et en passant un tableau de paramètres. La solution consiste à modifier les valeurs du tableau à référencer. Ce n'est pas élégant, mais il fonctionne.

call_user_func_array(array($stmt, 'bind_param'), makeValuesReferenced($passArray));

function makeValuesReferenced($arr){
    $refs = array();
    foreach($arr as $key => $value)
        $refs[$key] = &$arr[$key];
    return $refs;

}
45
répondu Dominic 2010-02-21 08:52:44

En fait, sachez qu'il y a un bug avec PHP 5.3.1 concernant les références et toute la famille de fonctions call:

Bogues PHP # 50394: argument de référence converti en valeur dans _ _ call

Le comportement que vous voyez peut être le résultat de ce bug et toute tentative de corriger le code sage peut causer des problèmes à long terme.

Le problème a été corrigé dans la version SVN de PHP. Jusqu'à ce que 5.3.2 soit publié, vous pouvez compiler une nouvelle version pour l'utiliser, ou rétrograder à une version antérieure.

6
répondu Andrew Moore 2010-02-21 08:59:22

Nous rencontrions le même problème avec ce code:

call_user_func(array($strCartHandler, 'CartPurchaseEvent'), $strCartEvent, $objToUser, null, $this);

Ma solution était de simplement sauter call_user_func complètement et de faire ceci:

$strCartHandler::CartPurchaseEvent($strCartEvent, $objToUser, null, $this);
3
répondu leek 2010-08-05 18:49:08

Je pense que ce qui est déconseillé est de passer une référence à travers une fonction. Dans la définition de la fonction vous faites quelque chose comme:

function(&$arg) {

}

Cela ne vous aide pas beaucoup mais vous n'avez probablement pas besoin de passer la référence de toute façon. Je suppose que vous pourriez essayer une fonction wrapper.

function wrapper($stmt, &$passArray) {
    call_user_func_array($stmt, $passArray);
}
2
répondu Louis 2010-01-12 00:38:09

Je pense que les fonctions mysqli_bind_param() et mysqli_bind_result() sont très difficiles à utiliser. J'ai rencontré la même difficulté que vous décrivez en les Utilisant en combinaison avec call_user_func_array()

Ma solution de contournement était d'arrêter d'utiliser mysqli et d'utiliser à la place PDO_mysql. Il a une utilisation beaucoup plus facile:

$pdoStmt->execute( $passArray );
0
répondu Bill Karwin 2010-01-12 00:19:11

Cela aidera:

<?php
call_user_func_array(Array($stmt, 'bind_param'), array(&$passArray));

function bind_param ($val)
{
    $val = (is_array($val)) ? $val[0] : $val;

    // operations...
}

?>
0
répondu Fatalist 2011-11-10 19:53:41

J'ai un problème similaire, le code actuel n'a pas fonctionné:

$query="Select id,name FROM mytable LIMIT ?,?";
$params=Array('ii');
array_push($params,$from_var);
array_push($params,$to_var);
...
$stmt=$link->prepare("$query");
$ref=new ReflectionClass('mysqli_stmt');
$method=$ref->getMethod("bind_param");
$method->invokeArgs($stmt,$params);
...

Il a dit que "le paramètre 2 à mysqli_stmt:: bind_param () devrait être une référence, valeur donnée"

Et puis, désespéré, j'ai essayé de prendre $from_var et $to_var entre guillemets. Et cela a fonctionné!

$params=Array('ii');
array_push($params,"$from_var");
array_push($params,"$to_var");

J'espère, ça aidera quelqu'un, bonne chance:)

0
répondu Kotaries 2015-05-04 10:02:41

Le deuxième paramètre doit être un tableau. apparemment, cela n'a été appliqué que dans 5.3

-1
répondu DeveloperChris 2012-08-06 17:05:04