2013-04-26 12 views
16

Ho una funzione che fa questo:Bind Param con array di parametri

function registerUser($firstName, $lastName, $address, $postcode, $email, $password) 
    { 
     $params = array($firstName, $lastName, $address, $postcode, $email, $password); 
     $result = $this->db->bind("INSERT INTO Users VALUES (?, ?, ?, ?, ?, ?)", 'ssssss', $params); 
    } 

che manda a mia classe base di dati, che fa questo:

public function bind($query, $type, $params) 
     { 

      $this->query = $query; 
      $stmt = $this->mysqli->prepare($this->query); 
      $stmt->bind_param($type, $param); 
      $stmt->execute; 
     } 

Il problema è questo non lo fa lavoro.

quello che speravo di fare, è stato quello di prendere la lista $params e lo hanno elencare loro dopo la $type, in modo che la query sarebbe simile:

$stmt->bind_param('ssssss', $firstName, $lastName, $address, $postcode, $email, $password); 

Ma ovviamente io sto andando su di esso dalla parte del torto modo.

c'è un modo per rendere l'array ... trasformato come era, in una lista da stampare nella fase di query bind_param?

+1

Vostri criteri esistono delle anomalie. Fai prima di bind_param un errore 'var_dump ($ this-> mysqli->);' per sapere cosa non va. – bwoebi

risposta

24

call_user_func_array()!

call_user_func_array(array($stmt, "bind_param"), array_merge(array($type), $params)); 

dovrebbe fare il lavoro

UPDATE: bisogna anche cambiare la vostra params array:

$params = array(&$firstName, &$lastName, &$address, &$postcode, &$email, &$password); 

come mysqli_stmt::bind_param aspetta il secondo ed i seguenti parametri per riferimento.


MODIFICA: la tua richiesta sembra essere errata. Forse hai meno campi di quanti ne hai. Do:

"INSERT INTO Users (field1, field2, field3, field4, field5, field6) VALUES (?, ?, ?, ?, ?, ?)" 

in cui si sostituisce il nome dei campi con i nomi corretti

+0

Avevi ragione - c'era un campo mancante. Ho risolto questo Tuttavia, utilizzando call_user_func_array come sopra, ottengo l'errore "Avviso: array_merge() [function.array-merge]: Argomento # 1 non è un array Avviso: call_user_func_array() si aspetta che il parametro 2 sia array , null dato " –

+0

@DavidG Usa quindi' array_merge (array (tipo $), $ params) '. Ma quando il tuo '$ params' non è impostato, non posso fare nulla come dovrebbe essere giusto. – bwoebi

+0

Grazie per il tuo aiuto :) Funziona quasi. Ho ricevuto un errore: Attenzione: il parametro 2 a mysqli_stmt :: bind_param() dovrebbe essere un riferimento, valore dato Quindi proverò a capire cosa si tratta di –

1

Il modo più semplice sarebbe a quanto pare il passaggio da mysqli a PDO

vi permetterà di farlo nel come vuoi e anche senza altre funzioni:

function registerUser($firstName, $lastName, $address, $postcode, $email, $password) 
{ 
    $sql = "INSERT INTO Users VALUES (NULL, ?, ?, ?, ?, ?, ?)"; 
    $stmt = $this->db->prepare($sql); 
    $stmt->execute(func_get_args()); 
} 
+2

il suo problema è: '$ stmt' non è un oggetto' mysqli_stmt' apparentemente ... – bwoebi

+0

@Il tuo Common Sense consideri PDO meglio su mysqli? Uso anche mysqli principalmente, ma non ne so molto di PDO. – Aris

+0

@Aris come puoi vedere, PDO richiede un numero notevolmente inferiore di codice. Queste 2 linee sono * tutte * necessarie. Non è richiesta alcuna funzione aggiuntiva. DOP può farlo fuori dalla scatola –

2

Hai ricevuto il tuo errore "Chiama ad un membro f unction bind_param() su un non oggetto "molto probabilmente, perché il tuo $ this-> mysqli-> prepara incontri di qualche tipo di errore. (vedi http://php.net/manual/de/mysqli.prepare.php - restituisce FALSE in caso di errore, che sembra essere il caso qui)

Dopo aver risolto il problema, provate questo invece della chiamata di $ stmt-> bind_param:

call_user_func_array(array($stmt, 'bind_param'), array_merge($type, $params)); 
0

È importante notare che mysqli_stmt_bind_param() richiede che i parametri vengano passati per riferimento, pertanto i parametri per call_user_func_array() devono essere un riferimento. Un esempio tratto dal contesto di classe:

function execute(string $query, string $type, array $params) 
{ 
    if (!$stmt = $this->mysqli->prepare($query)) 
     throw new \Exception('Prepare failed: ' . $query . PHP_EOL . $this->mysqli->error); 

    // call stmt->bind_param() with variables to bind passed as a reference 
    call_user_func_array( 
     array($stmt, 'bind_param'), 
     array_merge( 
      array($type), 
      array_map(function(&$item) { return $item; }, $params) 
     ) 
    ); 

    if (!$stmt->execute()) 
     throw new \Exception('Execute failed: ' . PHP_EOL . $stmt->error); 

} 

} 
8

Come da PHP 5.6 è possibile utilizzare l'argomento decompressione come alternativa a call_user_func_array ed è spesso da 3 a 4 volte più veloce.

$func = 'foo'; 
$values = array(1, 2); 
call_user_func_array($func, $values); 
//returns 3 

$func(...$values); 
//returns 3 
?> 

Tratto da here.

Così il vostro codice dovrebbe essere qualcosa di simile:

public function bind($query, $type, $params) 
     { 

      $this->query = $query; 
      $stmt = $this->mysqli->prepare($this->query); 
      $stmt->bind_param($type, ...$params); 
      $stmt->execute; 
     }