PHP + MYSQL:Associazione di parametri/risultati variabili con istruzioni preparate

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

  •  08-06-2019
  •  | 
  •  

Domanda

In un progetto che sto per concludere, ho scritto e implementato una soluzione di mappatura relazionale di oggetti per PHP.Prima che i dubbiosi e i sognatori gridino "come diavolo?", rilassati: non ho trovato un modo per far funzionare la rilegatura statica tardiva, sto solo lavorando nel miglior modo possibile.

Ad ogni modo, al momento non sto utilizzando istruzioni preparate per le query, perché non sono riuscito a trovare un modo per passare un numero variabile di argomenti al bind_params() O bind_result() metodi.

Perché devo supportare un numero variabile di argomenti, chiedi?Perché la superclasse dei miei modelli (pensa alla mia soluzione come un aspirante PHP ActiveRecord modificato) è dove viene definita l'interrogazione, e quindi il metodo find(), ad esempio, non sa quanti parametri avrebbe bisogno di associare .

Ora, ho già pensato di creare un elenco di argomenti e passare una stringa a eval(), ma non mi piace molto questa soluzione: preferisco semplicemente implementare i miei controlli di sicurezza e trasmettere istruzioni.

Qualcuno ha qualche suggerimento (o storie di successo) su come ottenere questo risultato?Se puoi aiutarmi a risolvere questo primo problema, forse possiamo affrontare l'associazione del set di risultati (qualcosa che sospetto sarà più difficile, o almeno più dispendioso in termini di risorse se comporta una query iniziale per determinare la struttura della tabella).

È stato utile?

Soluzione

In PHP puoi passare un numero variabile di argomenti a una funzione o metodo utilizzando call_user_func_array.Un esempio di metodo potrebbe essere:

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

La funzione verrà chiamata con ciascun membro dell'array passato come argomento proprio.

Altri suggerimenti

Devi assicurarti che $array_of_params sia un array di collegamenti alle variabili, non i valori stessi.Dovrebbe essere:

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

Poi...

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

Altrimenti (se si tratta di un array di valori) otterrai:

Avviso PHP:Il parametro 2 di mysqli_stmt::bind_param() dovrebbe essere un riferimento


Un altro esempio:

$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
}

e BOOOOM:

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

Non mi è consentito modificare, ma credo nel codice

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

Il riferimento davanti a $stmt non è necessario.Da $stmt è l'oggetto e bindparams è il metodo in quell'oggetto, il riferimento non è necessario.Dovrebbe essere:

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

Per ulteriori informazioni consultare il manuale PHP su Funzioni di richiamata."

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

Non ha funzionato per me nel mio ambiente, ma questa risposta mi ha messo sulla strada giusta.Ciò che effettivamente ha funzionato è stato:

$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();
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top