2008-08-15 5 views
7

Dans un projet que je suis sur le point de terminer, j'ai écrit et implémenté une solution de mapping objet-relationnel pour PHP. Avant que les sceptiques et les rêveurs crient «comment diable?», Détendez-vous - je n'ai pas trouvé un moyen de faire du travail de liaison statique en retard - je suis juste en train de contourner le problème de la meilleure façon possible.PHP + MYSQLI: Liaison de paramètre/résultat variable avec les instructions préparées

De toute façon, je n'utilise pas actuellement d'instructions préparées pour interroger, car je ne pouvais pas trouver un moyen de passer un nombre variable d'arguments aux méthodes bind_params() ou bind_result(). Pourquoi ai-je besoin de prendre en charge un nombre variable d'arguments, demandez-vous? Parce que la superclasse de mes modèles (pensez à ma solution en tant que wannabe PHP ActiveRecord piraté) est l'endroit où l'interrogation est définie, et donc la méthode find(), par exemple, ne sait pas combien de paramètres il faudrait lier . Maintenant, j'ai déjà pensé à construire une liste d'arguments et à passer 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 les transmettre déclarations.

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

Répondre

13

En PHP, vous pouvez passer un nombre variable d'arguments à une fonction ou une méthode en utilisant call_user_func_array. Un exemple pour une 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.

+0

Je pense que le nom de la fonction doit être 'bind_param' au lieu de' bindparams'. Au moins avec ma version 'mysqli' je l'utilise en tapant' $ stmt-> bind_param() ', pas' $ stmt-> bindparams() '. À votre santé! –

1

Je ne suis pas autorisé à modifier, mais je crois que dans le code

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

La référence en face de $ stmt 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. Il devrait être:

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

Pour plus d'informations, consultez le manuel PHP sur Callback Functions «

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

n'a pas fonctionné pour moi dans mon environnement, mais cette réponse m'a mis sur la bonne voie Que.. effectivement travaillé était:

$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(); 
2

Vous devez vous assurer que $ array_of_params est un tableau de des liens vers des variables, pas les valeurs du moi-même. 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 

Dans le cas contraire (si elle est un tableau de valeurs), vous obtenez:

PHP Warning: Paramètre 2 à mysqli_stmt :: bind_param() devrait être une référence


Un autre 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 BOOOOOM:

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