PHP + MYSQLI :Liaison paramètre/résultat variable avec des instructions préparées

StackOverflow https://stackoverflow.com/questions/12656

  •  08-06-2019
  •  | 
  •  

Question

Dans un projet que je suis sur le point de terminer, j'ai écrit et implémenté une solution de mappage objet-relationnel pour PHP.Avant que les sceptiques et les rêveurs ne s'écrient "Comment diable ?", détendez-vous -- je n'ai pas trouvé de moyen de faire fonctionner la reliure statique tardive -- je travaille simplement autour de ce problème de la meilleure façon possible.

Quoi qu'il en soit, je n'utilise pas actuellement d'instructions préparées pour les requêtes, car je n'ai pas trouvé de moyen de transmettre un nombre variable d'arguments au bind_params() ou bind_result() méthodes.

Pourquoi dois-je soutenir un nombre variable d’arguments, demandez-vous ?Parce que la superclasse de mes modèles (considérez ma solution comme un aspirant à PHP ActiveRecord piraté) est l'endroit où la requête est définie, et donc la méthode find(), par exemple, ne sait pas combien de paramètres elle aurait besoin de lier .

Maintenant, j'ai déjà pensé à créer une liste d'arguments et à transmettre une chaîne à eval(), mais je n'aime pas beaucoup cette solution : je préfère simplement implémenter mes propres contrôles de sécurité et transmettre les instructions.

Quelqu'un a-t-il des suggestions (ou des histoires de réussite) sur la façon d'y parvenir ?Si vous pouvez m'aider à résoudre ce premier problème, nous pourrions peut-être nous attaquer à la liaison du jeu de résultats (quelque chose, je suppose, sera plus difficile, ou du moins plus gourmand en ressources s'il implique une requête initiale pour déterminer la structure de la table).

Était-ce utile?

La solution

En PHP, vous pouvez transmettre un nombre variable d'arguments à une fonction ou une méthode en utilisant call_user_func_array.Un exemple de méthode serait :

call_user_func_array(array(&$stmt, 'bindparams'), $array_of_params);

La fonction sera appelée avec chaque membre du tableau passé comme son propre argument.

Autres conseils

Vous devez vous assurer que $array_of_params est un tableau de liens vers des variables, pas se valorise.Devrait être:

$array_of_params[0] = &$param_string; //link to variable that stores types

Et puis...

$param_string .= "i";
$user_id_var = $_GET['user_id'];//
$array_of_params[] = &$user_id_var; //link to variable that stores value

Sinon (s'il s'agit d'un tableau de valeurs), vous obtiendrez :

Avertissement PHP :Le paramètre 2 de mysqli_stmt::bind_param() devrait être une référence


Encore un exemple :

$bind_names[] = implode($types); //putting types of parameters in a string
for ($i = 0; $i < count($params); $i++)
{
   $bind_name = 'bind'.$i; //generate a name for variable bind1, bind2, bind3...
   $$bind_name = $params[$i]; //create a variable with this name and put value in it
   $bind_names[] = & $$bind_name; //put a link to this variable in array
}

et BOUOOOM :

call_user_func_array( array ($stmt, 'bind_param'), $bind_names); 

Je n'ai pas le droit de modifier, mais je crois au code

call_user_func_array(array(&$stmt, 'bindparams'), $array_of_params);

La référence devant $stmt n’est pas nécessaire.Depuis $stmt est l'objet et bindparams est la méthode dans cet objet, la référence n'est pas nécessaire.Ça devrait être:

call_user_func_array(array($stmt, 'bindparams'), $array_of_params);

Pour plus d'informations, consultez le manuel PHP sur Fonctions de rappel."

call_user_func_array(array(&$stmt, 'bindparams'), $array_of_params);

Cela n'a pas fonctionné pour moi dans mon environnement mais cette réponse m'a mis sur la bonne voie.Ce qui a réellement fonctionné, c'est :

$sitesql = '';
$array_of_params = array();
foreach($_POST['multiselect'] as $value){
    if($sitesql!=''){
        $sitesql .= "OR siteID=? ";
        $array_of_params[0] .= 'i';
        $array_of_params[] = $value;
    }else{
        $sitesql = " siteID=? ";
        $array_of_params[0] .= 'i';
        $array_of_params[] = $value;
    }
}

$stmt = $linki->prepare("SELECT IFNULL(SUM(hours),0) FROM table WHERE ".$sitesql." AND week!='0000-00-00'");
call_user_func_array(array(&$stmt, 'bind_param'), $array_of_params);
$stmt->execute();
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top