2012-08-13 16 views
5

Devo selezionare alcune righe dal database utilizzando l'operatore IN. Voglio farlo usando una dichiarazione preparata. Questo è il mio codice:Istruzioni preparate da MySQLi con l'operatore IN

<?php 
$lastnames = array('braun', 'piorkowski', 'mason', 'nash'); 
$in_statement = '"' . implode('", "', $lastnames) . '"'; //"braun", "piorkowski", "mason", "nash" 

$data_res = $_DB->prepare('SELECT `id`, `name`, `age` FROM `users` WHERE `lastname` IN (?)'); 
$data_res->bind_param('s', $in_statement); 
$data_res->execute(); 
$result = $data_res->get_result(); 
while ($data = $result->fetch_array(MYSQLI_ASSOC)) { 
    ... 
} 
?> 

Ma non restituisce nulla sebbene tutti i dati siano presenti nel database.

E ancora: se passo $in_statement direttamente per interrogarlo ed eseguirlo, i dati verranno restituiti. Quindi il problema appare nella preparazione.

Stavo cercando la domanda in Google, ma non è stato un successo. Cosa c'è che non va nel mio codice?
Grazie per l'aiuto!

+3

Non è possibile utilizzare un singolo parametro per la clausola IN. Deve essere: 'WHERE lastname IN (?,?,?,?)' – andrewsi

+1

Ok, grazie mille!) Sembra un po 'ingombrante. – kpotehin

risposta

4

Recentemente ho trovato la soluzione per la mia domanda. Forse non è il modo migliore per farlo, ma funziona bene! Dimostra che ho sbagliato :)

<?php 
$lastnames = array('braun', 'piorkowski', 'mason', 'nash'); 
$arParams = array(); 

foreach($lastnames as $key => $value) //recreate an array with parameters explicitly passing every parameter by reference 
    $arParams[] = &$lastnames[$key]; 

$count_params = count($arParams); 

$int = str_repeat('i',$count_params); //add type for each variable (i,d,s,b); you can also determine type of the variable automatically (is_int, is_float, is_string) in loop, but i don't need it 
array_unshift($arParams,$int); 

$q = array_fill(0,$count_params,'?'); //form string of question marks for statement 
$params = implode(',',$q); 

$data_res = $_DB->prepare('SELECT `id`, `name`, `age` FROM `users` WHERE `lastname` IN ('.$params.')'); 
call_user_func_array(array($data_res, 'bind_param'), $arParams); 
$data_res->execute(); 
$result = $data_res->get_result(); 
while ($data = $result->fetch_array(MYSQLI_ASSOC)) { 
    ... 
} 

$result->free(); 
$data_res->close(); 
?> 
2

Le dichiarazioni preparate hanno lo scopo di evitare esattamente quello che stai cercando di farlo fare :)

Per arrivare a questo lavoro si deve applicare questo passo:

$escaped_lastnames = join(',', array_map(array($_DB, 'real_escape_string'), $lastnames)); 

Esso mappa la stringa corretta funzione di escape per il tuo database su ogni articolo di $lastnames. Al termine, inserisci questo valore direttamente nella query, ovvero senza utilizzare i parametri associati.

+0

Grazie, Jack, ma ho trovato il modo di fare questa domanda tramite una dichiarazione preparata. Sto usando call_user_func_array (array ($ data_res, 'bind_param'), $ arParams); invece regolare bind_param. $ arParams contiene esattamente i tipi di variabili e queste variabili) – kpotehin

+0

Ho appena postato il mio codice come risposta) – kpotehin

+2

@kpotehin sicuro, se davvero devi (ab) usare le dichiarazioni preparate per questo, puoi ovviamente :) personalmente non vedo il vantaggio, a meno che non debba essere eseguito più volte all'interno di un'esecuzione di php –

Problemi correlati